--HG--
extra : commitid : KSEbGPeZZae
This commit is contained in:
Wes Kocher 2016-01-25 14:07:49 -08:00
Родитель 3872a2da46 36c834aaa6
Коммит 9d24ca2703
273 изменённых файлов: 43253 добавлений и 43960 удалений

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

@ -123,3 +123,4 @@ b297a6727acfd21e757ddd38cd61894812666265 FIREFOX_AURORA_36_BASE
fcef8ded82219c89298b4e376cfbdfba79a1d35a FIREFOX_AURORA_43_BASE fcef8ded82219c89298b4e376cfbdfba79a1d35a FIREFOX_AURORA_43_BASE
67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_BASE 67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_BASE
99137d6d4061f408ae0869122649d8bdf489cc30 FIREFOX_AURORA_45_BASE 99137d6d4061f408ae0869122649d8bdf489cc30 FIREFOX_AURORA_45_BASE
67c66c2878aed17ae3096d7db483ddbb2293c503 FIREFOX_AURORA_46_BASE

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

@ -22,5 +22,5 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Bug 1240627 - Enable AVX2 optimizations in ffvpx on Mac
Merge day clobber

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

@ -9,6 +9,9 @@ add_task(function* () {
const ENGINE_NAME = "Foo"; const ENGINE_NAME = "Foo";
var contextMenu; var contextMenu;
// We want select events to be fired.
yield new Promise(resolve => SpecialPowers.pushPrefEnv({"set": [["dom.select_events.enabled", true]]}, resolve));
let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
let originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR"); let originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR");
envService.set("XPCSHELL_TEST_PROFILE_DIR", "1"); envService.set("XPCSHELL_TEST_PROFILE_DIR", "1");

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

@ -1 +1 @@
46.0a1 47.0a1

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

@ -1 +1 @@
46.0a1 47.0a1

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

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files. # hardcoded milestones in the tree from these two files.
#-------------------------------------------------------- #--------------------------------------------------------
46.0a1 47.0a1

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

@ -2309,7 +2309,7 @@ public:
// Rooter class for MozMap; this is what we mostly use in the codegen. // Rooter class for MozMap; this is what we mostly use in the codegen.
template<typename T> template<typename T>
class MOZ_RAII MozMapRooter : private JS::CustomAutoRooter class MOZ_RAII MozMapRooter final : private JS::CustomAutoRooter
{ {
public: public:
MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap

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

@ -412,8 +412,8 @@ private:
// Class for easily setting up a rooted typed array object on the stack // Class for easily setting up a rooted typed array object on the stack
template<typename ArrayType> template<typename ArrayType>
class MOZ_RAII RootedTypedArray : public ArrayType, class MOZ_RAII RootedTypedArray final : public ArrayType,
private TypedArrayRooter<ArrayType> private TypedArrayRooter<ArrayType>
{ {
public: public:
explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :

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

@ -549,6 +549,9 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
} else { } else {
// StartRemoteDrawingInRegion can mutate mInvalidRegion. // StartRemoteDrawingInRegion can mutate mInvalidRegion.
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion); mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
if (!mDrawTarget) {
return;
}
mInvalidRect = mInvalidRegion.GetBounds(); mInvalidRect = mInvalidRegion.GetBounds();
if (mInvalidRect.IsEmpty()) { if (mInvalidRect.IsEmpty()) {
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion); mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);

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

@ -2087,7 +2087,7 @@ RangeAnalysis::analyzeLoopPhi(MBasicBlock* header, LoopIterationBound* loopBound
return; return;
if (!phi->range()) if (!phi->range())
phi->setRange(new(alloc()) Range()); phi->setRange(new(alloc()) Range(phi));
LinearSum initialSum(alloc()); LinearSum initialSum(alloc());
if (!initialSum.add(initial, 1)) if (!initialSum.add(initial, 1))

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

@ -0,0 +1,64 @@
---
Language: Cpp
# BasedOnStyle: Mozilla
AccessModifierOffset: -2
AlignAfterOpenBracket: true
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
BinPackArguments: true
ColumnLimit: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: true
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: false
Standard: Cpp03
IndentWidth: 4
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Linux
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
...

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

@ -1 +1 @@
NSS_3_21_RTM NSS_3_22_BETA2

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

@ -3496,6 +3496,9 @@ shutdown:
/* Allocated by a PL_strdup call in SECU_GetModulePassword. */ /* Allocated by a PL_strdup call in SECU_GetModulePassword. */
PL_strfree(pwdata.data); PL_strfree(pwdata.data);
} }
if (email) {
PL_strfree(email);
}
/* Open the batch command file. /* Open the batch command file.
* *

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

@ -42,7 +42,7 @@ const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) }, { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) }, { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) }, { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
{ 0, } { 0 }
}; };
/* returns 0 for success, -1 for failure (EOF encountered) */ /* returns 0 for success, -1 for failure (EOF encountered) */

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

@ -1,575 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "secutil.h"
#include "plgetopt.h"
#include "cert.h"
#include "secoid.h"
#include "cryptohi.h"
/* maximum supported modulus length in bits (indicate problem if over this) */
#define MAX_MODULUS (1024)
static void Usage(char *progName)
{
fprintf(stderr, "Usage: %s [aAvf] [certtocheck] [issuingcert]\n",
progName);
fprintf(stderr, "%-20s Cert to check is base64 encoded\n",
"-a");
fprintf(stderr, "%-20s Issuer's cert is base64 encoded\n",
"-A");
fprintf(stderr, "%-20s Verbose (indicate decoding progress etc.)\n",
"-v");
fprintf(stderr, "%-20s Force sanity checks even if pretty print fails.\n",
"-f");
fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
"-o output");
fprintf(stderr, "%-20s Specify the input type (no default)\n",
"-t type");
exit(-1);
}
/*
* Check integer field named fieldName, printing out results and
* returning the length of the integer in bits
*/
static
int checkInteger(SECItem *intItem, char *fieldName, int verbose)
{
int len, bitlen;
if (verbose) {
printf("Checking %s\n", fieldName);
}
len = intItem->len;
if (len && (intItem->data[0] & 0x80)) {
printf("PROBLEM: %s is NEGATIVE 2's-complement integer.\n",
fieldName);
}
/* calculate bit length and check for unnecessary leading zeros */
bitlen = len << 3;
if (len > 1 && intItem->data[0] == 0) {
/* leading zero byte(s) */
if (!(intItem->data[1] & 0x80)) {
printf("PROBLEM: %s has unneeded leading zeros. Violates DER.\n",
fieldName);
}
/* strip leading zeros in length calculation */
{
int i=0;
while (bitlen > 8 && intItem->data[i] == 0) {
bitlen -= 8;
i++;
}
}
}
return bitlen;
}
static
void checkName(CERTName *n, char *fieldName, int verbose)
{
char *v=0;
if (verbose) {
printf("Checking %s\n", fieldName);
}
v = CERT_GetCountryName(n);
if (!v) {
printf("PROBLEM: %s lacks Country Name (C)\n",
fieldName);
}
PORT_Free(v);
v = CERT_GetOrgName(n);
if (!v) {
printf("PROBLEM: %s lacks Organization Name (O)\n",
fieldName);
}
PORT_Free(v);
v = CERT_GetOrgUnitName(n);
if (!v) {
printf("WARNING: %s lacks Organization Unit Name (OU)\n",
fieldName);
}
PORT_Free(v);
v = CERT_GetCommonName(n);
if (!v) {
printf("PROBLEM: %s lacks Common Name (CN)\n",
fieldName);
}
PORT_Free(v);
}
static
SECStatus
OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
SECItem *sig, SECAlgorithmID *sigAlgorithm)
{
SECStatus rv;
VFYContext *cx;
SECOidData *sigAlgOid, *oiddata;
SECOidTag hashAlgTag;
int showDigestOid=0;
cx = VFY_CreateContextWithAlgorithmID(key, sig, sigAlgorithm, &hashAlgTag,
NULL);
if (cx == NULL)
return SECFailure;
sigAlgOid = SECOID_FindOID(&sigAlgorithm->algorithm);
if (sigAlgOid == 0)
return SECFailure;
if (showDigestOid) {
oiddata = SECOID_FindOIDByTag(hashAlgTag);
if ( oiddata ) {
printf("PROBLEM: (cont) Digest OID is %s\n", oiddata->desc);
} else {
SECU_PrintAsHex(stdout,
&oiddata->oid, "PROBLEM: UNKNOWN OID", 0);
}
}
rv = VFY_Begin(cx);
if (rv == SECSuccess) {
rv = VFY_Update(cx, buf, len);
if (rv == SECSuccess)
rv = VFY_End(cx);
}
VFY_DestroyContext(cx, PR_TRUE);
return rv;
}
static
SECStatus
OurVerifySignedData(CERTSignedData *sd, CERTCertificate *cert)
{
SECItem sig;
SECKEYPublicKey *pubKey = 0;
SECStatus rv;
/* check the certificate's validity */
rv = CERT_CertTimesValid(cert);
if ( rv ) {
return(SECFailure);
}
/* get cert's public key */
pubKey = CERT_ExtractPublicKey(cert);
if ( !pubKey ) {
return(SECFailure);
}
/* check the signature */
sig = sd->signature;
DER_ConvertBitString(&sig);
rv = OurVerifyData(sd->data.data, sd->data.len, pubKey, &sig,
&sd->signatureAlgorithm);
SECKEY_DestroyPublicKey(pubKey);
if ( rv ) {
return(SECFailure);
}
return(SECSuccess);
}
static
CERTCertificate *createEmptyCertificate(void)
{
PLArenaPool *arena = 0;
CERTCertificate *c = 0;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( !arena ) {
return 0;
}
c = (CERTCertificate *) PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
if (c) {
c->referenceCount = 1;
c->arena = arena;
} else {
PORT_FreeArena(arena,PR_TRUE);
}
return c;
}
int main(int argc, char **argv)
{
int verbose=0, force=0;
int ascii=0, issuerAscii=0;
char *progName=0;
PRFileDesc *inFile=0, *issuerCertFile=0;
SECItem derCert, derIssuerCert;
PLArenaPool *arena=0;
CERTSignedData *signedData=0;
CERTCertificate *cert=0, *issuerCert=0;
SECKEYPublicKey *rsapubkey=0;
SECAlgorithmID md5WithRSAEncryption, md2WithRSAEncryption;
SECAlgorithmID sha1WithRSAEncryption, rsaEncryption;
SECItem spk;
int selfSigned=0;
int invalid=0;
char *inFileName = NULL, *issuerCertFileName = NULL;
PLOptState *optstate;
PLOptStatus status;
SECStatus rv;
PORT_Memset(&md5WithRSAEncryption, 0, sizeof(md5WithRSAEncryption));
PORT_Memset(&md2WithRSAEncryption, 0, sizeof(md2WithRSAEncryption));
PORT_Memset(&sha1WithRSAEncryption, 0, sizeof(sha1WithRSAEncryption));
PORT_Memset(&rsaEncryption, 0, sizeof(rsaEncryption));
progName = strrchr(argv[0], '/');
progName = progName ? progName+1 : argv[0];
optstate = PL_CreateOptState(argc, argv, "aAvf");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case 'v':
verbose = 1;
break;
case 'f':
force = 1;
break;
case 'a':
ascii = 1;
break;
case 'A':
issuerAscii = 1;
break;
case '\0':
if (!inFileName)
inFileName = PL_strdup(optstate->value);
else if (!issuerCertFileName)
issuerCertFileName = PL_strdup(optstate->value);
else
Usage(progName);
break;
}
}
if (!inFileName || !issuerCertFileName || status == PL_OPT_BAD) {
/* insufficient or excess args */
Usage(progName);
}
inFile = PR_Open(inFileName, PR_RDONLY, 0);
if (!inFile) {
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
progName, inFileName);
exit(1);
}
issuerCertFile = PR_Open(issuerCertFileName, PR_RDONLY, 0);
if (!issuerCertFile) {
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
progName, issuerCertFileName);
exit(1);
}
if (SECU_ReadDERFromFile(&derCert, inFile, ascii, PR_FALSE) != SECSuccess) {
printf("Couldn't read input certificate as DER binary or base64\n");
exit(1);
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == 0) {
fprintf(stderr,"%s: can't allocate scratch arena!", progName);
exit(1);
}
if (issuerCertFile) {
CERTSignedData *issuerCertSD=0;
if (SECU_ReadDERFromFile(&derIssuerCert, issuerCertFile, issuerAscii,
PR_FALSE) != SECSuccess) {
printf("Couldn't read issuer certificate as DER binary or base64.\n");
exit(1);
}
issuerCertSD = PORT_ArenaZNew(arena, CERTSignedData);
if (!issuerCertSD) {
fprintf(stderr,"%s: can't allocate issuer signed data!", progName);
exit(1);
}
rv = SEC_ASN1DecodeItem(arena, issuerCertSD,
SEC_ASN1_GET(CERT_SignedDataTemplate),
&derIssuerCert);
if (rv) {
fprintf(stderr, "%s: Issuer cert isn't X509 SIGNED Data?\n",
progName);
exit(1);
}
issuerCert = createEmptyCertificate();
if (!issuerCert) {
printf("%s: can't allocate space for issuer cert.", progName);
exit(1);
}
rv = SEC_ASN1DecodeItem(arena, issuerCert,
SEC_ASN1_GET(CERT_CertificateTemplate),
&issuerCertSD->data);
if (rv) {
printf("%s: Does not appear to be an X509 Certificate.\n",
progName);
exit(1);
}
}
signedData = PORT_ArenaZNew(arena,CERTSignedData);
if (!signedData) {
fprintf(stderr,"%s: can't allocate signedData!", progName);
exit(1);
}
rv = SEC_ASN1DecodeItem(arena, signedData,
SEC_ASN1_GET(CERT_SignedDataTemplate),
&derCert);
if (rv) {
fprintf(stderr, "%s: Does not appear to be X509 SIGNED Data.\n",
progName);
exit(1);
}
if (verbose) {
printf("Decoded ok as X509 SIGNED data.\n");
}
cert = createEmptyCertificate();
if (!cert) {
fprintf(stderr, "%s: can't allocate cert", progName);
exit(1);
}
rv = SEC_ASN1DecodeItem(arena, cert,
SEC_ASN1_GET(CERT_CertificateTemplate),
&signedData->data);
if (rv) {
fprintf(stderr, "%s: Does not appear to be an X509 Certificate.\n",
progName);
exit(1);
}
if (verbose) {
printf("Decoded ok as an X509 certificate.\n");
}
SECU_RegisterDynamicOids();
rv = SECU_PrintSignedData(stdout, &derCert, "Certificate", 0,
(SECU_PPFunc)SECU_PrintCertificate);
if (rv) {
fprintf(stderr, "%s: Unable to pretty print cert. Error: %d\n",
progName, PORT_GetError());
if (!force) {
exit(1);
}
}
/* Do various checks on the cert */
printf("\n");
/* Check algorithms */
rv = SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption,
SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, NULL);
if (rv) {
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION.\n",
progName);
exit(1);
}
rv = SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption,
SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, NULL);
if (rv) {
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION.\n",
progName);
exit(1);
}
rv = SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption,
SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, NULL);
if (rv) {
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION.\n",
progName);
exit(1);
}
rv = SECOID_SetAlgorithmID(arena, &rsaEncryption,
SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
if (rv) {
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_RSA_ENCRYPTION.\n",
progName);
exit(1);
}
{
int isMD5RSA = (SECOID_CompareAlgorithmID(&cert->signature,
&md5WithRSAEncryption) == 0);
int isMD2RSA = (SECOID_CompareAlgorithmID(&cert->signature,
&md2WithRSAEncryption) == 0);
int isSHA1RSA = (SECOID_CompareAlgorithmID(&cert->signature,
&sha1WithRSAEncryption) == 0);
if (verbose) {
printf("\nDoing algorithm checks.\n");
}
if (!(isMD5RSA || isMD2RSA || isSHA1RSA)) {
printf("PROBLEM: Signature not PKCS1 MD5, MD2, or SHA1 + RSA.\n");
} else if (!isMD5RSA) {
printf("WARNING: Signature not PKCS1 MD5 with RSA Encryption\n");
}
if (SECOID_CompareAlgorithmID(&cert->signature,
&signedData->signatureAlgorithm)) {
printf("PROBLEM: Algorithm in sig and certInfo don't match.\n");
}
}
if (SECOID_CompareAlgorithmID(&cert->subjectPublicKeyInfo.algorithm,
&rsaEncryption)) {
printf("PROBLEM: Public key algorithm is not PKCS1 RSA Encryption.\n");
}
/* Check further public key properties */
spk = cert->subjectPublicKeyInfo.subjectPublicKey;
DER_ConvertBitString(&spk);
if (verbose) {
printf("\nsubjectPublicKey DER\n");
rv = DER_PrettyPrint(stdout, &spk, PR_FALSE);
printf("\n");
}
rsapubkey = (SECKEYPublicKey *)
PORT_ArenaZAlloc(arena,sizeof(SECKEYPublicKey));
if (!rsapubkey) {
fprintf(stderr, "%s: rsapubkey allocation failed.\n", progName);
exit(1);
}
rv = SEC_ASN1DecodeItem(arena, rsapubkey,
SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), &spk);
if (rv) {
printf("PROBLEM: subjectPublicKey is not a DER PKCS1 RSAPublicKey.\n");
} else {
int mlen;
int pubexp;
if (verbose) {
printf("Decoded RSA Public Key ok. Doing key checks.\n");
}
PORT_Assert(rsapubkey->keyType == rsaKey); /* XXX RSA */
mlen = checkInteger(&rsapubkey->u.rsa.modulus, "Modulus", verbose);
printf("INFO: Public Key modulus length in bits: %d\n", mlen);
if (mlen > MAX_MODULUS) {
printf("PROBLEM: Modulus length exceeds %d bits.\n",
MAX_MODULUS);
}
if (mlen < 512) {
printf("WARNING: Short modulus.\n");
}
if (mlen != (1 << (ffs(mlen)-1))) {
printf("WARNING: Unusual modulus length (not a power of two).\n");
}
checkInteger(&rsapubkey->u.rsa.publicExponent, "Public Exponent",
verbose);
pubexp = DER_GetInteger(&rsapubkey->u.rsa.publicExponent);
if (pubexp != 17 && pubexp != 3 && pubexp != 65537) {
printf("WARNING: Public exponent not any of: 3, 17, 65537\n");
}
}
/* Name checks */
checkName(&cert->issuer, "Issuer Name", verbose);
checkName(&cert->subject, "Subject Name", verbose);
if (issuerCert) {
SECComparison c =
CERT_CompareName(&cert->issuer, &issuerCert->subject);
if (c) {
printf("PROBLEM: Issuer Name and Subject in Issuing Cert differ\n");
}
}
/* Check if self-signed */
selfSigned = (CERT_CompareName(&cert->issuer, &cert->subject) == 0);
if (selfSigned) {
printf("INFO: Certificate is self signed.\n");
} else {
printf("INFO: Certificate is NOT self-signed.\n");
}
/* Validity time check */
if (CERT_CertTimesValid(cert) == SECSuccess) {
printf("INFO: Inside validity period of certificate.\n");
} else {
printf("PROBLEM: Not in validity period of certificate.\n");
invalid = 1;
}
/* Signature check if self-signed */
if (selfSigned && !invalid) {
if (rsapubkey->u.rsa.modulus.len) {
SECStatus ver;
if (verbose) {
printf("Checking self signature.\n");
}
ver = OurVerifySignedData(signedData, cert);
if (ver != SECSuccess) {
printf("PROBLEM: Verification of self-signature failed!\n");
} else {
printf("INFO: Self-signature verifies ok.\n");
}
} else {
printf("INFO: Not checking signature due to key problems.\n");
}
} else if (!selfSigned && !invalid && issuerCert) {
SECStatus ver;
ver = OurVerifySignedData(signedData, issuerCert);
if (ver != SECSuccess) {
printf("PROBLEM: Verification of issuer's signature failed!\n");
} else {
printf("INFO: Issuer's signature verifies ok.\n");
}
} else {
printf("INFO: Not checking signature.\n");
}
return 0;
}

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

@ -1,19 +0,0 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CORE_DEPTH = ../..
# MODULE public and private header directories are implicitly REQUIRED.
MODULE = nss
# This next line is used by .mk files
# and gets translated into $LINCS in manifest.mnw
REQUIRES = seccmd dbm
DEFINES = -DNSPR20
CSRCS = checkcert.c
PROGRAM = checkcert

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

@ -5344,9 +5344,9 @@ rsa_siggen_test(char *reqfn)
NSSLOWKEYPublicKey * rsa_public_key; NSSLOWKEYPublicKey * rsa_public_key;
NSSLOWKEYPrivateKey * rsa_private_key; NSSLOWKEYPrivateKey * rsa_private_key;
NSSLOWKEYPrivateKey low_RSA_private_key = { NULL, NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
NSSLOWKEYRSAKey, }; NSSLOWKEYRSAKey };
NSSLOWKEYPublicKey low_RSA_public_key = { NULL, NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
NSSLOWKEYRSAKey, }; NSSLOWKEYRSAKey };
low_RSA_private_key.u.rsa = *rsaBlapiPrivKey; low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
low_RSA_public_key.u.rsa = *rsaBlapiPublicKey; low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
@ -5610,7 +5610,7 @@ rsa_sigver_test(char *reqfn)
SECStatus rv = SECFailure; SECStatus rv = SECFailure;
NSSLOWKEYPublicKey * rsa_public_key; NSSLOWKEYPublicKey * rsa_public_key;
NSSLOWKEYPublicKey low_RSA_public_key = { NULL, NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
NSSLOWKEYRSAKey, }; NSSLOWKEYRSAKey };
/* convert to a low RSA public key */ /* convert to a low RSA public key */
low_RSA_public_key.u.rsa = rsaBlapiPublicKey; low_RSA_public_key.u.rsa = rsaBlapiPublicKey;

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

@ -30,6 +30,13 @@ getInteger256(const unsigned char *data, unsigned int nb)
val = (data[0] << 16) | (data[1] << 8) | data[2]; val = (data[0] << 16) | (data[1] << 8) | data[2];
break; break;
case 4: case 4:
/* If the most significant bit of data[0] is 1, val would be negative.
* Treat it as an error.
*/
if (data[0] & 0x80) {
PORT_SetError(SEC_ERROR_BAD_DER);
return -1;
}
val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
break; break;
default: default:
@ -232,6 +239,10 @@ prettyPrintObjectID(FILE *out, const unsigned char *data,
if (rv < 0) if (rv < 0)
return rv; return rv;
if (len == 0) {
PORT_SetError(SEC_ERROR_BAD_DER);
return -1;
}
val = data[0]; val = data[0];
i = val % 40; i = val % 40;
val = val / 40; val = val / 40;
@ -282,24 +293,17 @@ prettyPrintObjectID(FILE *out, const unsigned char *data,
} }
} }
/* rv = prettyNewline(out);
* Finally, on a new line, print the raw bytes (if requested). if (rv < 0)
*/ return rv;
if (raw) {
rv = prettyNewline(out);
if (rv < 0) {
PORT_SetError(SEC_ERROR_IO);
return rv;
}
for (i = 0; i < len; i++) { if (raw) {
rv = prettyPrintByte(out, *data++, level); rv = prettyPrintLeaf(out, data, len, level);
if (rv < 0) if (rv < 0)
return rv; return rv;
}
} }
return prettyNewline(out); return 0;
} }
static char *prettyTagType [32] = { static char *prettyTagType [32] = {
@ -423,6 +427,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
*indefinitep = PR_FALSE; *indefinitep = PR_FALSE;
lbyte = *data++; lbyte = *data++;
lenLen = 1;
if (lbyte >= 0x80) { if (lbyte >= 0x80) {
/* Multibyte length */ /* Multibyte length */
unsigned nb = (unsigned) (lbyte & 0x7f); unsigned nb = (unsigned) (lbyte & 0x7f);
@ -444,7 +449,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
*lenp = 0; *lenp = 0;
*indefinitep = PR_TRUE; *indefinitep = PR_TRUE;
} }
lenLen = nb + 1; lenLen += nb;
if (raw) { if (raw) {
unsigned int i; unsigned int i;
@ -459,7 +464,6 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
} }
} else { } else {
*lenp = lbyte; *lenp = lbyte;
lenLen = 1;
if (raw) { if (raw) {
rv = prettyPrintByte(out, lbyte, lv); rv = prettyPrintByte(out, lbyte, lv);
if (rv < 0) if (rv < 0)

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

@ -420,6 +420,9 @@ SECU_DefaultSSLDir(void)
if (!dir) if (!dir)
return NULL; return NULL;
if (strlen(dir) >= PR_ARRAY_SIZE(sslDir)) {
return NULL;
}
sprintf(sslDir, "%s", dir); sprintf(sslDir, "%s", dir);
if (sslDir[strlen(sslDir)-1] == '/') if (sslDir[strlen(sslDir)-1] == '/')
@ -3300,6 +3303,7 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
errstr = "[unknown usage]."; errstr = "[unknown usage].";
break; break;
} }
break;
case SEC_ERROR_INADEQUATE_CERT_TYPE: case SEC_ERROR_INADEQUATE_CERT_TYPE:
flags = (unsigned int)((char *)node->arg - (char *)NULL); flags = (unsigned int)((char *)node->arg - (char *)NULL);
switch (flags) { switch (flags) {
@ -3326,6 +3330,7 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
errstr = "[unknown usage]."; errstr = "[unknown usage].";
break; break;
} }
break;
case SEC_ERROR_UNKNOWN_ISSUER: case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_UNTRUSTED_ISSUER: case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:

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

@ -154,7 +154,7 @@ testFunctionRef testFnRefTable[] = {
{"test_mutex3", test_mutex3}, {"test_mutex3", test_mutex3},
{"test_object", test_object}, {"test_object", test_object},
{"test_oid", test_oid}, {"test_oid", test_oid},
/* {"test_rwlock", test_rwlock, }*/ /* {"test_rwlock", test_rwlock }*/
{"test_string", test_string}, {"test_string", test_string},
{"test_string2", test_string2}, {"test_string2", test_string2},
{"build_chain", build_chain}, {"build_chain", build_chain},

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

@ -28,7 +28,7 @@ const SEC_ASN1Template seckey_PQGParamsTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) }, { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) }, { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) }, { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
{ 0, } { 0 }
}; };

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

@ -6,16 +6,36 @@
DEPTH = .. DEPTH = ..
# MODULE = seccmd # MODULE = seccmd
REQUIRES = nss nspr libdbm SOFTOKEN_SRCDIRS=
NSS_SRCDIRS=
LIB_SRCDIRS=
DIRS = lib \ ifdef NSS_BUILD_UTIL_ONLY
REQUIRES = nspr
else
REQUIRES = nss nspr libdbm
LIB_SRCDIRS = \
lib \
$(NULL)
endif
ifndef NSS_BUILD_UTIL_ONLY
SOFTOKEN_SRCDIRS = \
$(BLTEST_SRCDIR) \
$(FIPSTEST_SRCDIR) \
$(LOWHASHTEST_SRCDIR) \
$(SHLIBSIGN_SRCDIR) \
$(NULL)
endif
ifndef NSS_BUILD_SOFTOKEN_ONLY
ifndef NSS_BUILD_UTIL_ONLY
NSS_SRCDIRS = \
addbuiltin \ addbuiltin \
atob \ atob \
$(BLTEST_SRCDIR) \
btoa \ btoa \
certcgi \ certcgi \
certutil \ certutil \
checkcert \
chktest \ chktest \
crlutil \ crlutil \
crmftest \ crmftest \
@ -23,8 +43,6 @@ DIRS = lib \
derdump \ derdump \
digest \ digest \
httpserv \ httpserv \
$(FIPSTEST_SRCDIR) \
$(LOWHASHTEST_SRCDIR) \
listsuites \ listsuites \
makepqg \ makepqg \
multinit \ multinit \
@ -47,7 +65,6 @@ DIRS = lib \
selfserv \ selfserv \
signtool \ signtool \
signver \ signver \
$(SHLIBSIGN_SRCDIR) \
smimetools \ smimetools \
ssltap \ ssltap \
strsclnt \ strsclnt \
@ -58,6 +75,13 @@ DIRS = lib \
vfyserv \ vfyserv \
modutil \ modutil \
$(NULL) $(NULL)
endif
endif
DIRS = \
$(LIB_SRCDIRS) \
$(SOFTOKEN_SRCDIRS) \
$(NSS_SRCDIRS)
TEMPORARILY_DONT_BUILD = \ TEMPORARILY_DONT_BUILD = \
$(NULL) $(NULL)

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

@ -193,8 +193,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
goto loser; goto loser;
} }
_this->relativePath = PR_Strdup(subval->string); _this->relativePath = PR_Strdup(subval->string);
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
subiter = NULL;
/* Absolute directory */ /* Absolute directory */
} else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) { } else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
@ -206,8 +205,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
goto loser; goto loser;
} }
_this->absolutePath = PR_Strdup(subval->string); _this->absolutePath = PR_Strdup(subval->string);
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
subiter = NULL;
/* file permissions */ /* file permissions */
} else if( !PORT_Strcasecmp(subpair->key, } else if( !PORT_Strcasecmp(subpair->key,
@ -227,8 +225,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
goto loser; goto loser;
} }
gotPerms = PR_TRUE; gotPerms = PR_TRUE;
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
subiter = NULL;
} }
} else { } else {
if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) { if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
@ -260,12 +257,10 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
loser: loser:
if(iter) { if(iter) {
Pk11Install_ListIter_delete(iter); Pk11Install_ListIter_delete(&iter);
PR_Free(iter);
} }
if(subiter) { if(subiter) {
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
} }
return errStr; return errStr;
} }
@ -636,12 +631,15 @@ Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this)
void void
Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad) Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad)
{ {
char *str = NULL;
PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>"); PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>");
PAD(pad); printf("Digits: "); PAD(pad); printf("Digits: ");
if(_this->numDigits == 0) { if(_this->numDigits == 0) {
printf("None\n"); printf("None\n");
} else { } else {
printf("%s\n", Pk11Install_PlatformName_GetVerString(_this)); str = Pk11Install_PlatformName_GetVerString(_this);
printf("%s\n", str);
PR_Free(str);
} }
PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>"); PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>");
} }
@ -770,9 +768,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
goto loser; goto loser;
} }
_this->moduleFile = PR_Strdup(subval->string); _this->moduleFile = PR_Strdup(subval->string);
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter = NULL;
gotModuleFile = PR_TRUE; gotModuleFile = PR_TRUE;
} else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){ } else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
if(gotModuleName) { if(gotModuleName) {
@ -788,9 +784,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
goto loser; goto loser;
} }
_this->moduleName = PR_Strdup(subval->string); _this->moduleName = PR_Strdup(subval->string);
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter = NULL;
gotModuleName = PR_TRUE; gotModuleName = PR_TRUE;
} else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) { } else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
endptr=NULL; endptr=NULL;
@ -813,9 +807,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
Pk11Install_PlatformName_GetString(&_this->name)); Pk11Install_PlatformName_GetString(&_this->name));
goto loser; goto loser;
} }
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter=NULL;
gotMech = PR_TRUE; gotMech = PR_TRUE;
} else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) { } else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
endptr=NULL; endptr=NULL;
@ -838,9 +830,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
Pk11Install_PlatformName_GetString(&_this->name)); Pk11Install_PlatformName_GetString(&_this->name));
goto loser; goto loser;
} }
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter=NULL;
gotCipher = PR_TRUE; gotCipher = PR_TRUE;
} else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) { } else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
if(gotFiles) { if(gotFiles) {
@ -1089,9 +1079,7 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
} }
} }
} }
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter = NULL;
} else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) { } else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
subiter = Pk11Install_ListIter_new(pair->list); subiter = Pk11Install_ListIter_new(pair->list);
_this->numPlatforms = pair->list->numPairs; _this->numPlatforms = pair->list->numPairs;
@ -1109,9 +1097,7 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
} }
} }
} }
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter = NULL;
} }
} }
} }
@ -1192,14 +1178,10 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
loser: loser:
if(iter) { if(iter) {
Pk11Install_ListIter_delete(iter); Pk11Install_ListIter_delete(&iter);
PR_Free(iter);
iter = NULL;
} }
if(subiter) { if(subiter) {
Pk11Install_ListIter_delete(subiter); Pk11Install_ListIter_delete(&subiter);
PR_Free(subiter);
subiter = NULL;
} }
return errStr; return errStr;
} }
@ -1348,10 +1330,12 @@ Pk11Install_ListIter_new(const Pk11Install_ValueList *_list)
/****************************************************************************/ /****************************************************************************/
void void
Pk11Install_ListIter_delete(Pk11Install_ListIter* _this) Pk11Install_ListIter_delete(Pk11Install_ListIter** _this)
{ {
_this->list=NULL; (*_this)->list=NULL;
_this->current=NULL; (*_this)->current=NULL;
PR_Free(*_this);
*_this=NULL;
} }
/****************************************************************************/ /****************************************************************************/

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

@ -124,7 +124,7 @@ Pk11Install_ListIter_init(Pk11Install_ListIter* _this);
Pk11Install_ListIter* Pk11Install_ListIter*
Pk11Install_ListIter_new(const Pk11Install_ValueList* _list); Pk11Install_ListIter_new(const Pk11Install_ValueList* _list);
void void
Pk11Install_ListIter_delete(Pk11Install_ListIter* _this); Pk11Install_ListIter_delete(Pk11Install_ListIter** _this);
void void
Pk11Install_ListIter_reset(Pk11Install_ListIter* _this); Pk11Install_ListIter_reset(Pk11Install_ListIter* _this);
Pk11Install_Value* Pk11Install_Value*

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

@ -44,8 +44,8 @@ SEC_ASN1Template CERTSignatureDataTemplate[] =
offsetof(CERTSignedData,signatureAlgorithm), offsetof(CERTSignedData,signatureAlgorithm),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING, { SEC_ASN1_BIT_STRING,
offsetof(CERTSignedData,signature), }, offsetof(CERTSignedData,signature) },
{ 0, } { 0 }
}; };

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

@ -51,6 +51,7 @@ EXTRA_SHARED_LIBS += \
$(NULL) $(NULL)
endif endif
ifndef NSS_BUILD_SOFTOKEN_ONLY
PKIXLIB = \ PKIXLIB = \
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \
@ -64,35 +65,100 @@ PKIXLIB = \
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX) $(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX)
endif
# can't do this in manifest.mn because OS_ARCH isn't defined there. NSS_LIBS_1=
SECTOOL_LIB=
NSS_LIBS_2=
NSS_LIBS_3=
NSS_LIBS_4=
ifneq ($(NSS_BUILD_UTIL_ONLY),1)
SECTOOL_LIB = \
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
$(NULL)
else
SECTOOL_LIB = \
$(NULL)
endif
ifneq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
ifeq ($(OS_ARCH), WINNT) ifeq ($(OS_ARCH), WINNT)
# breakdown for windows
EXTRA_LIBS += \ NSS_LIBS_1 = \
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \ $(NULL)
NSS_LIBS_2 = \
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
$(SOFTOKENLIB) \ $(NULL)
$(CRYPTOLIB) \ NSS_LIBS_3 = \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
$(PKIXLIB) \ $(PKIXLIB) \
$(DBMLIB) \ $(DBMLIB) \
$(NULL)
NSS_LIBS_4 = \
$(SQLITE_LIB_DIR)/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(LIB_SUFFIX) \ $(SQLITE_LIB_DIR)/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(LIB_SUFFIX) \
$(NSSUTIL_LIB_DIR)/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \ $(NSSUTIL_LIB_DIR)/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
$(NULL) $(NULL)
else
# breakdown for others
NSS_LIBS_1 = \
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
$(NULL)
SECTOOL_LIB = \
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
$(NULL)
NSS_LIBS_2 = \
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
$(NULL)
NSS_LIBS_3 = \
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
$(NULL)
NSS_LIBS_4 = \
$(DBMLIB) \
$(PKIXLIB) \
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
$(NULL)
endif
endif
# can't do this in manifest.mn because OS_ARCH isn't defined there.
ifeq ($(OS_ARCH), WINNT)
EXTRA_LIBS += \
$(NSS_LIBS_1) \
$(SECTOOL_LIB) \
$(NSS_LIBS_2) \
$(SOFTOKENLIB) \
$(CRYPTOLIB) \
$(NSS_LIBS_3) \
$(NSS_LIBS_4) \
$(NULL)
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS) # $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
#OS_LIBS += \ #OS_LIBS += \
@ -102,30 +168,13 @@ EXTRA_LIBS += \
else else
EXTRA_LIBS += \ EXTRA_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \ $(NSS_LIBS_1) \
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \ $(SECTOOL_LIB) \
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \ $(NSS_LIBS_2) \
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
$(SOFTOKENLIB) \ $(SOFTOKENLIB) \
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \ $(NSS_LIBS_3) \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
$(CRYPTOLIB) \ $(CRYPTOLIB) \
$(DBMLIB) \ $(NSS_LIBS_4) \
$(PKIXLIB) \
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
$(NULL) $(NULL)
ifeq ($(OS_ARCH), AIX) ifeq ($(OS_ARCH), AIX)

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

@ -225,6 +225,7 @@ PrintParameterUsage()
"-W override default DHE server weak parameters support, 0: disable, 1: enable\n" "-W override default DHE server weak parameters support, 0: disable, 1: enable\n"
"-c Restrict ciphers\n" "-c Restrict ciphers\n"
"-Y prints cipher values allowed for parameter -c and exits\n" "-Y prints cipher values allowed for parameter -c and exits\n"
"-G enables the extended master secret extension [RFC7627]\n"
, stderr); , stderr);
} }

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

@ -110,6 +110,7 @@ void printSecurityInfo(PRFileDesc *fd)
{ {
CERTCertificate * cert; CERTCertificate * cert;
const SECItemArray *csa; const SECItemArray *csa;
const SECItem *scts;
SSL3Statistics * ssl3stats = SSL_GetStatistics(); SSL3Statistics * ssl3stats = SSL_GetStatistics();
SECStatus result; SECStatus result;
SSLChannelInfo channel; SSLChannelInfo channel;
@ -162,6 +163,11 @@ void printSecurityInfo(PRFileDesc *fd)
fprintf(stderr, "Received %d Cert Status items (OCSP stapled data)\n", fprintf(stderr, "Received %d Cert Status items (OCSP stapled data)\n",
csa->len); csa->len);
} }
scts = SSL_PeerSignedCertTimestamps(fd);
if (scts && scts->len) {
fprintf(stderr, "Received a Signed Certificate Timestamp of length"
" %u\n", scts->len);
}
} }
void void
@ -184,7 +190,7 @@ static void PrintUsageHeader(const char *progName)
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n" "Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
"[-D | -d certdir] [-C] [-b | -R root-module] \n" "[-D | -d certdir] [-C] [-b | -R root-module] \n"
"[-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n" "[-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n"
"[-V [min-version]:[max-version]] [-K] [-T]\n" "[-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
"[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n", "[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n",
progName); progName);
} }
@ -232,6 +238,7 @@ static void PrintParameterUsage(void)
fprintf(stderr, "%-20s Enable compression.\n", "-z"); fprintf(stderr, "%-20s Enable compression.\n", "-z");
fprintf(stderr, "%-20s Enable false start.\n", "-g"); fprintf(stderr, "%-20s Enable false start.\n", "-g");
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T"); fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
fprintf(stderr, "%-20s Enable the signed_certificate_timestamp extension.\n", "-U");
fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G"); fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n" fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
"%-20s -F once means: require for server cert only\n" "%-20s -F once means: require for server cert only\n"
@ -250,6 +257,7 @@ static void PrintParameterUsage(void)
fprintf(stderr, "%-20s Enforce using an IPv4 destination address\n", "-4"); fprintf(stderr, "%-20s Enforce using an IPv4 destination address\n", "-4");
fprintf(stderr, "%-20s Enforce using an IPv6 destination address\n", "-6"); fprintf(stderr, "%-20s Enforce using an IPv6 destination address\n", "-6");
fprintf(stderr, "%-20s (Options -4 and -6 cannot be combined.)\n", ""); fprintf(stderr, "%-20s (Options -4 and -6 cannot be combined.)\n", "");
fprintf(stderr, "%-20s Enable the extended master secret extension [RFC7627]\n", "-G");
} }
static void Usage(const char *progName) static void Usage(const char *progName)
@ -920,6 +928,7 @@ int main(int argc, char **argv)
int enableCompression = 0; int enableCompression = 0;
int enableFalseStart = 0; int enableFalseStart = 0;
int enableCertStatus = 0; int enableCertStatus = 0;
int enableSignedCertTimestamps = 0;
int forceFallbackSCSV = 0; int forceFallbackSCSV = 0;
int enableExtendedMasterSecret = 0; int enableExtendedMasterSecret = 0;
PRSocketOptionData opt; PRSocketOptionData opt;
@ -970,7 +979,7 @@ int main(int argc, char **argv)
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions); SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
optstate = PL_CreateOptState(argc, argv, optstate = PL_CreateOptState(argc, argv,
"46BCDFGKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz"); "46BCDFGKM:OR:STUV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) { switch (optstate->option) {
case '?': case '?':
@ -1023,6 +1032,8 @@ int main(int argc, char **argv)
case 'T': enableCertStatus = 1; break; case 'T': enableCertStatus = 1; break;
case 'U': enableSignedCertTimestamps = 1; break;
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value, case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
enabledVersions, enableSSL2, enabledVersions, enableSSL2,
&enabledVersions, &enableSSL2) != SECSuccess) { &enabledVersions, &enableSSL2) != SECSuccess) {
@ -1400,6 +1411,14 @@ int main(int argc, char **argv)
} }
} }
/* enable Signed Certificate Timestamps. */
rv = SSL_OptionSet(s, SSL_ENABLE_SIGNED_CERT_TIMESTAMPS,
enableSignedCertTimestamps);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling signed cert timestamps");
return 1;
}
SSL_SetPKCS11PinArg(s, &pwdata); SSL_SetPKCS11PinArg(s, &pwdata);
serverCertAuth.dbHandle = CERT_GetDefaultCertDB(); serverCertAuth.dbHandle = CERT_GetDefaultCertDB();

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

@ -104,7 +104,7 @@ endif
DLL_SUFFIX = dll DLL_SUFFIX = dll
ifdef NS_USE_GCC ifdef NS_USE_GCC
OS_CFLAGS += -mwindows -mms-bitfields -Werror OS_CFLAGS += -mwindows -mms-bitfields
_GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY) _GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB)) DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
ifdef BUILD_OPT ifdef BUILD_OPT

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

@ -21,7 +21,7 @@ ifndef WARNING_CFLAGS
# and fixing this would require rearchitecture # and fixing this would require rearchitecture
WARNING_CFLAGS += -Qunused-arguments WARNING_CFLAGS += -Qunused-arguments
# -Wno-parentheses-equality : because clang warns about macro expansions # -Wno-parentheses-equality : because clang warns about macro expansions
OS_CFLAGS += $(call disable_warning,parentheses-equality) WARNING_CFLAGS += $(call disable_warning,parentheses-equality)
ifdef BUILD_OPT ifdef BUILD_OPT
# clang is unable to handle glib's expansion of strcmp and similar for optimized # clang is unable to handle glib's expansion of strcmp and similar for optimized
# builds, so ignore the resulting errors. # builds, so ignore the resulting errors.

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

@ -10,3 +10,4 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

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

@ -2,8 +2,8 @@ GTest-based Unit Tests
This directory contains GTest-based unit tests for NSS libssl. This directory contains GTest-based unit tests for NSS libssl.
These aren't built by default, because they require C++. If your environment doesn't have C++ compiler suitable to build these tests,
To build them, set ``NSS_BUILD_GTESTS=1'' you may disable them using ``NSS_DISABLE_GTESTS=1''
Once built, they are run as part of running ``test/all.sh'' Once built, they are run as part of running ``test/all.sh''
You can run just the GTests by running ``tests/ssl_gtests/ssl_gtests.sh'' You can run just the GTests by running ``tests/ssl_gtests/ssl_gtests.sh''

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

@ -0,0 +1,27 @@
#! gmake
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include ../../cmd/platlibs.mk
include ../../cmd/platrules.mk
MKPROG = $(CCC)
MKSHLIB = $(CCC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
ifeq (WINNT,$(OS_ARCH))
# -EHsc because gtest has exception handlers
OS_CFLAGS += -EHsc -nologo
# http://www.suodenjoki.dk/us/archive/2010/min-max.htm
OS_CFLAGS += -DNOMINMAX
# Linking to winsock to get htonl
OS_LIBS += Ws2_32.lib
# On windows, we need to create the parent directory
# Needed because we include files from a subdirectory
MAKE_OBJDIR = $(INSTALL) -D $(dir $@)
else
CXXFLAGS += -std=c++0x
endif

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

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef scoped_ptrs_h__
#define scoped_ptrs_h__
#include "keyhi.h"
namespace nss_test {
struct ScopedDelete {
void operator()(PK11SlotInfo* slot) { PK11_FreeSlot(slot); }
void operator()(SECItem* item) { SECITEM_FreeItem(item, true); }
void operator()(PK11SymKey* key) { PK11_FreeSymKey(key); }
void operator()(SECKEYPublicKey* key) { SECKEY_DestroyPublicKey(key); }
void operator()(SECKEYPrivateKey* key) { SECKEY_DestroyPrivateKey(key); }
void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); }
void operator()(CERTSubjectPublicKeyInfo* spki) {
SECKEY_DestroySubjectPublicKeyInfo(spki);
}
};
template<class T>
struct ScopedMaybeDelete {
void operator()(T* ptr) { if (ptr) { ScopedDelete del; del(ptr); } }
};
#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped ## x
SCOPED(PK11SlotInfo);
SCOPED(SECItem);
SCOPED(PK11SymKey);
SCOPED(SECKEYPublicKey);
SCOPED(SECKEYPrivateKey);
SCOPED(SECAlgorithmID);
SCOPED(CERTSubjectPublicKeyInfo);
#undef SCOPED
} // namespace nss_test
#endif

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

@ -26,6 +26,7 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (4) Include "local" platform-dependent assignments (OPTIONAL). # # (4) Include "local" platform-dependent assignments (OPTIONAL). #
####################################################################### #######################################################################
include ../common/gtest.mk
####################################################################### #######################################################################
# (5) Execute "global" rules. (OPTIONAL) # # (5) Execute "global" rules. (OPTIONAL) #
@ -41,12 +42,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk
####################################################################### #######################################################################
# (7) Execute "local" rules. (OPTIONAL). # # (7) Execute "local" rules. (OPTIONAL). #
####################################################################### #######################################################################
MKSHLIB = $(CCC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
ifeq (WINNT,$(OS_ARCH))
# -EHsc because gtest has exception handlers
OS_CFLAGS += -EHsc
# On windows, we need to create the parent directory
# Needed because we include files from a subdirectory
MAKE_OBJDIR = $(INSTALL) -D $(dir $@)
endif

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

@ -7,5 +7,6 @@ DEPTH = ..
DIRS = \ DIRS = \
google_test \ google_test \
pk11_gtest \
ssl_gtest \ ssl_gtest \
$(NULL) $(NULL)

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

@ -1,5 +1,5 @@
#! gmake #! gmake
# #
# This Source Code Form is subject to the terms of the Mozilla Public # This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -20,11 +20,12 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (3) Include "component" configuration information. (OPTIONAL) # # (3) Include "component" configuration information. (OPTIONAL) #
####################################################################### #######################################################################
####################################################################### #######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). # # (4) Include "local" platform-dependent assignments (OPTIONAL). #
####################################################################### #######################################################################
include ../platlibs.mk include ../common/gtest.mk
####################################################################### #######################################################################
# (5) Execute "global" rules. (OPTIONAL) # # (5) Execute "global" rules. (OPTIONAL) #
@ -37,12 +38,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
####################################################################### #######################################################################
####################################################################### #######################################################################
# (7) Execute "local" rules. (OPTIONAL). # # (7) Execute "local" rules. (OPTIONAL). #
####################################################################### #######################################################################
include ../platrules.mk

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

@ -0,0 +1,22 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CORE_DEPTH = ../..
DEPTH = ../..
MODULE = nss
CPPSRCS = \
pk11_pbkdf2_unittest.cc \
pk11_prf_unittest.cc \
pk11_rsapss_unittest.cc \
pk11_gtest.cc \
$(NULL)
INCLUDES += -I$(CORE_DEPTH)/external_tests/google_test/gtest/include \
-I$(CORE_DEPTH)/external_tests/common
REQUIRES = nspr nss libdbm gtest
PROGRAM = pk11_gtest
EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX)

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

@ -0,0 +1,21 @@
#include "nspr.h"
#include "nss.h"
#include "ssl.h"
#include <cstdlib>
#define GTEST_HAS_RTTI 0
#include "gtest/gtest.h"
int main(int argc, char **argv) {
// Start the tests
::testing::InitGoogleTest(&argc, argv);
NSS_NoDB_Init(nullptr);
NSS_SetDomesticPolicy();
int rv = RUN_ALL_TESTS();
NSS_Shutdown();
return rv;
}

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

@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nss.h"
#include "pk11pub.h"
#include <memory>
#include "gtest/gtest.h"
#include "scoped_ptrs.h"
namespace nss_test {
static unsigned char* ToUcharPtr(std::string& str) {
return const_cast<unsigned char*>(
reinterpret_cast<const unsigned char*>(str.c_str()));
}
class Pkcs11Pbkdf2Test : public ::testing::Test {
public:
void Derive(std::vector<uint8_t>& derived, SECOidTag hash_alg)
{
// Shared between test vectors.
const unsigned int iterations = 4096;
std::string pass("passwordPASSWORDpassword");
std::string salt("saltSALTsaltSALTsaltSALTsaltSALTsalt");
// Derivation must succeed with the right values.
EXPECT_TRUE(DeriveBytes(pass, salt, derived, hash_alg, iterations));
// Derivation must fail when the password is bogus.
std::string bogusPass("PasswordPASSWORDpassword");
EXPECT_FALSE(DeriveBytes(bogusPass, salt, derived, hash_alg, iterations));
// Derivation must fail when the salt is bogus.
std::string bogusSalt("SaltSALTsaltSALTsaltSALTsaltSALTsalt");
EXPECT_FALSE(DeriveBytes(pass, bogusSalt, derived, hash_alg, iterations));
// Derivation must fail when using the wrong hash function.
SECOidTag next_hash_alg = static_cast<SECOidTag>(hash_alg + 1);
EXPECT_FALSE(DeriveBytes(pass, salt, derived, next_hash_alg, iterations));
// Derivation must fail when using the wrong number of iterations.
EXPECT_FALSE(DeriveBytes(pass, salt, derived, hash_alg, iterations + 1));
}
private:
bool DeriveBytes(std::string& pass, std::string& salt,
std::vector<uint8_t>& derived, SECOidTag hash_alg,
unsigned int iterations)
{
SECItem passItem = { siBuffer, ToUcharPtr(pass),
static_cast<unsigned int>(pass.length()) };
SECItem saltItem = { siBuffer, ToUcharPtr(salt),
static_cast<unsigned int>(salt.length()) };
// Set up PBKDF2 params.
ScopedSECAlgorithmID alg_id(
PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2, hash_alg, hash_alg,
derived.size(), iterations, &saltItem));
// Derive.
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
ScopedPK11SymKey symKey(
PK11_PBEKeyGen(slot.get(), alg_id.get(), &passItem, false, nullptr));
SECStatus rv = PK11_ExtractKeyValue(symKey.get());
EXPECT_EQ(rv, SECSuccess);
SECItem* keyData = PK11_GetKeyData(symKey.get());
return !memcmp(&derived[0], keyData->data, keyData->len);
}
};
// RFC 6070 <http://tools.ietf.org/html/rfc6070>
TEST_F(Pkcs11Pbkdf2Test, DeriveKnown1) {
std::vector<uint8_t> derived = {
0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, 0x80, 0xc8, 0xd8, 0x36,
0x62, 0xc0, 0xe4, 0x4a, 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, 0x38
};
Derive(derived, SEC_OID_HMAC_SHA1);
}
// https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
TEST_F(Pkcs11Pbkdf2Test, DeriveKnown2) {
std::vector<uint8_t> derived = {
0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 0x14, 0xb8,
0x11, 0x6e, 0x84, 0xcf, 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 0x53, 0xe1, 0xc6, 0x35, 0x51, 0x8c,
0x7d, 0xac, 0x47, 0xe9
};
Derive(derived, SEC_OID_HMAC_SHA256);
}
} // namespace nss_test

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

@ -8,13 +8,10 @@
#include "pk11pub.h" #include "pk11pub.h"
#include <memory> #include <memory>
#include "gtest_utils.h" #include "gtest/gtest.h"
namespace nss_test { namespace nss_test {
#define CONST_UINT8_TO_UCHAR(a) const_cast<unsigned char*>( \
static_cast<const unsigned char *>(a))
const size_t kPmsSize = 48; const size_t kPmsSize = 48;
const size_t kMasterSecretSize = 48; const size_t kMasterSecretSize = 48;
const size_t kPrfSeedSizeSha256 = 32; const size_t kPrfSeedSizeSha256 = 32;
@ -143,7 +140,7 @@ class TlsPrfTest : public ::testing::Test {
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS master_params = { CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS master_params = {
hash_mech, hash_mech,
toUcharPtr(kPrfSeed), toUcharPtr(kPrfSeed),
seed_len, static_cast<CK_ULONG>(seed_len),
version version
}; };
params_.data = reinterpret_cast<unsigned char*>(&master_params); params_.data = reinterpret_cast<unsigned char*>(&master_params);

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

@ -0,0 +1,246 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nss.h"
#include "pk11pub.h"
#include "sechash.h"
#include <memory>
#include "gtest/gtest.h"
#include "scoped_ptrs.h"
namespace nss_test {
// RSA-PSS test vectors, pss-vect.txt, Example 1: A 1024-bit RSA Key Pair
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
const uint8_t kTestVector1Spki[] = {
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
0x81, 0x81, 0x00, 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e, 0x36, 0xad, 0x52,
0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56,
0xff, 0xed, 0xb1, 0x62, 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94,
0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab, 0xfc, 0xe0,
0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d, 0x5b, 0x2b, 0x8b, 0x6d, 0xf5,
0xd6, 0x71, 0xef, 0x63, 0x77, 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70,
0xe2, 0x59, 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3, 0xf0,
0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f, 0x64, 0xc4, 0xef, 0x22,
0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8, 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21,
0x37, 0x02, 0x03, 0x01, 0x00, 0x01
};
// RSA-PSS test vectors, pss-vect.txt, Example 1.1
const uint8_t kTestVector1Data[] = {
0xcd, 0xc8, 0x7d, 0xa2, 0x23, 0xd7, 0x86, 0xdf, 0x3b, 0x45, 0xe0, 0xbb, 0xbc,
0x72, 0x13, 0x26, 0xd1, 0xee, 0x2a, 0xf8, 0x06, 0xcc, 0x31, 0x54, 0x75, 0xcc,
0x6f, 0x0d, 0x9c, 0x66, 0xe1, 0xb6, 0x23, 0x71, 0xd4, 0x5c, 0xe2, 0x39, 0x2e,
0x1a, 0xc9, 0x28, 0x44, 0xc3, 0x10, 0x10, 0x2f, 0x15, 0x6a, 0x0d, 0x8d, 0x52,
0xc1, 0xf4, 0xc4, 0x0b, 0xa3, 0xaa, 0x65, 0x09, 0x57, 0x86, 0xcb, 0x76, 0x97,
0x57, 0xa6, 0x56, 0x3b, 0xa9, 0x58, 0xfe, 0xd0, 0xbc, 0xc9, 0x84, 0xe8, 0xb5,
0x17, 0xa3, 0xd5, 0xf5, 0x15, 0xb2, 0x3b, 0x8a, 0x41, 0xe7, 0x4a, 0xa8, 0x67,
0x69, 0x3f, 0x90, 0xdf, 0xb0, 0x61, 0xa6, 0xe8, 0x6d, 0xfa, 0xae, 0xe6, 0x44,
0x72, 0xc0, 0x0e, 0x5f, 0x20, 0x94, 0x57, 0x29, 0xcb, 0xeb, 0xe7, 0x7f, 0x06,
0xce, 0x78, 0xe0, 0x8f, 0x40, 0x98, 0xfb, 0xa4, 0x1f, 0x9d, 0x61, 0x93, 0xc0,
0x31, 0x7e, 0x8b, 0x60, 0xd4, 0xb6, 0x08, 0x4a, 0xcb, 0x42, 0xd2, 0x9e, 0x38,
0x08, 0xa3, 0xbc, 0x37, 0x2d, 0x85, 0xe3, 0x31, 0x17, 0x0f, 0xcb, 0xf7, 0xcc,
0x72, 0xd0, 0xb7, 0x1c, 0x29, 0x66, 0x48, 0xb3, 0xa4, 0xd1, 0x0f, 0x41, 0x62,
0x95, 0xd0, 0x80, 0x7a, 0xa6, 0x25, 0xca, 0xb2, 0x74, 0x4f, 0xd9, 0xea, 0x8f,
0xd2, 0x23, 0xc4, 0x25, 0x37, 0x02, 0x98, 0x28, 0xbd, 0x16, 0xbe, 0x02, 0x54,
0x6f, 0x13, 0x0f, 0xd2, 0xe3, 0x3b, 0x93, 0x6d, 0x26, 0x76, 0xe0, 0x8a, 0xed,
0x1b, 0x73, 0x31, 0x8b, 0x75, 0x0a, 0x01, 0x67, 0xd0
};
const uint8_t kTestVector1Sig[] = {
0x90, 0x74, 0x30, 0x8f, 0xb5, 0x98, 0xe9, 0x70, 0x1b, 0x22, 0x94, 0x38, 0x8e,
0x52, 0xf9, 0x71, 0xfa, 0xac, 0x2b, 0x60, 0xa5, 0x14, 0x5a, 0xf1, 0x85, 0xdf,
0x52, 0x87, 0xb5, 0xed, 0x28, 0x87, 0xe5, 0x7c, 0xe7, 0xfd, 0x44, 0xdc, 0x86,
0x34, 0xe4, 0x07, 0xc8, 0xe0, 0xe4, 0x36, 0x0b, 0xc2, 0x26, 0xf3, 0xec, 0x22,
0x7f, 0x9d, 0x9e, 0x54, 0x63, 0x8e, 0x8d, 0x31, 0xf5, 0x05, 0x12, 0x15, 0xdf,
0x6e, 0xbb, 0x9c, 0x2f, 0x95, 0x79, 0xaa, 0x77, 0x59, 0x8a, 0x38, 0xf9, 0x14,
0xb5, 0xb9, 0xc1, 0xbd, 0x83, 0xc4, 0xe2, 0xf9, 0xf3, 0x82, 0xa0, 0xd0, 0xaa,
0x35, 0x42, 0xff, 0xee, 0x65, 0x98, 0x4a, 0x60, 0x1b, 0xc6, 0x9e, 0xb2, 0x8d,
0xeb, 0x27, 0xdc, 0xa1, 0x2c, 0x82, 0xc2, 0xd4, 0xc3, 0xf6, 0x6c, 0xd5, 0x00,
0xf1, 0xff, 0x2b, 0x99, 0x4d, 0x8a, 0x4e, 0x30, 0xcb, 0xb3, 0x3c
};
// RSA-PSS test vectors, pss-vect.txt, Example 10: A 2048-bit RSA Key Pair
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
const uint8_t kTestVector2Spki[] = {
0x30, 0x82, 0x01, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0e, 0x00, 0x30, 0x82,
0x01, 0x09, 0x02, 0x82, 0x01, 0x00, 0xa5, 0xdd, 0x86, 0x7a, 0xc4, 0xcb, 0x02,
0xf9, 0x0b, 0x94, 0x57, 0xd4, 0x8c, 0x14, 0xa7, 0x70, 0xef, 0x99, 0x1c, 0x56,
0xc3, 0x9c, 0x0e, 0xc6, 0x5f, 0xd1, 0x1a, 0xfa, 0x89, 0x37, 0xce, 0xa5, 0x7b,
0x9b, 0xe7, 0xac, 0x73, 0xb4, 0x5c, 0x00, 0x17, 0x61, 0x5b, 0x82, 0xd6, 0x22,
0xe3, 0x18, 0x75, 0x3b, 0x60, 0x27, 0xc0, 0xfd, 0x15, 0x7b, 0xe1, 0x2f, 0x80,
0x90, 0xfe, 0xe2, 0xa7, 0xad, 0xcd, 0x0e, 0xef, 0x75, 0x9f, 0x88, 0xba, 0x49,
0x97, 0xc7, 0xa4, 0x2d, 0x58, 0xc9, 0xaa, 0x12, 0xcb, 0x99, 0xae, 0x00, 0x1f,
0xe5, 0x21, 0xc1, 0x3b, 0xb5, 0x43, 0x14, 0x45, 0xa8, 0xd5, 0xae, 0x4f, 0x5e,
0x4c, 0x7e, 0x94, 0x8a, 0xc2, 0x27, 0xd3, 0x60, 0x40, 0x71, 0xf2, 0x0e, 0x57,
0x7e, 0x90, 0x5f, 0xbe, 0xb1, 0x5d, 0xfa, 0xf0, 0x6d, 0x1d, 0xe5, 0xae, 0x62,
0x53, 0xd6, 0x3a, 0x6a, 0x21, 0x20, 0xb3, 0x1a, 0x5d, 0xa5, 0xda, 0xbc, 0x95,
0x50, 0x60, 0x0e, 0x20, 0xf2, 0x7d, 0x37, 0x39, 0xe2, 0x62, 0x79, 0x25, 0xfe,
0xa3, 0xcc, 0x50, 0x9f, 0x21, 0xdf, 0xf0, 0x4e, 0x6e, 0xea, 0x45, 0x49, 0xc5,
0x40, 0xd6, 0x80, 0x9f, 0xf9, 0x30, 0x7e, 0xed, 0xe9, 0x1f, 0xff, 0x58, 0x73,
0x3d, 0x83, 0x85, 0xa2, 0x37, 0xd6, 0xd3, 0x70, 0x5a, 0x33, 0xe3, 0x91, 0x90,
0x09, 0x92, 0x07, 0x0d, 0xf7, 0xad, 0xf1, 0x35, 0x7c, 0xf7, 0xe3, 0x70, 0x0c,
0xe3, 0x66, 0x7d, 0xe8, 0x3f, 0x17, 0xb8, 0xdf, 0x17, 0x78, 0xdb, 0x38, 0x1d,
0xce, 0x09, 0xcb, 0x4a, 0xd0, 0x58, 0xa5, 0x11, 0x00, 0x1a, 0x73, 0x81, 0x98,
0xee, 0x27, 0xcf, 0x55, 0xa1, 0x3b, 0x75, 0x45, 0x39, 0x90, 0x65, 0x82, 0xec,
0x8b, 0x17, 0x4b, 0xd5, 0x8d, 0x5d, 0x1f, 0x3d, 0x76, 0x7c, 0x61, 0x37, 0x21,
0xae, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01
};
// RSA-PSS test vectors, pss-vect.txt, Example 10.1
const uint8_t kTestVector2Data[] = {
0x88, 0x31, 0x77, 0xe5, 0x12, 0x6b, 0x9b, 0xe2, 0xd9, 0xa9, 0x68, 0x03, 0x27,
0xd5, 0x37, 0x0c, 0x6f, 0x26, 0x86, 0x1f, 0x58, 0x20, 0xc4, 0x3d, 0xa6, 0x7a,
0x3a, 0xd6, 0x09
};
const uint8_t kTestVector2Sig[] = {
0x82, 0xc2, 0xb1, 0x60, 0x09, 0x3b, 0x8a, 0xa3, 0xc0, 0xf7, 0x52, 0x2b, 0x19,
0xf8, 0x73, 0x54, 0x06, 0x6c, 0x77, 0x84, 0x7a, 0xbf, 0x2a, 0x9f, 0xce, 0x54,
0x2d, 0x0e, 0x84, 0xe9, 0x20, 0xc5, 0xaf, 0xb4, 0x9f, 0xfd, 0xfd, 0xac, 0xe1,
0x65, 0x60, 0xee, 0x94, 0xa1, 0x36, 0x96, 0x01, 0x14, 0x8e, 0xba, 0xd7, 0xa0,
0xe1, 0x51, 0xcf, 0x16, 0x33, 0x17, 0x91, 0xa5, 0x72, 0x7d, 0x05, 0xf2, 0x1e,
0x74, 0xe7, 0xeb, 0x81, 0x14, 0x40, 0x20, 0x69, 0x35, 0xd7, 0x44, 0x76, 0x5a,
0x15, 0xe7, 0x9f, 0x01, 0x5c, 0xb6, 0x6c, 0x53, 0x2c, 0x87, 0xa6, 0xa0, 0x59,
0x61, 0xc8, 0xbf, 0xad, 0x74, 0x1a, 0x9a, 0x66, 0x57, 0x02, 0x28, 0x94, 0x39,
0x3e, 0x72, 0x23, 0x73, 0x97, 0x96, 0xc0, 0x2a, 0x77, 0x45, 0x5d, 0x0f, 0x55,
0x5b, 0x0e, 0xc0, 0x1d, 0xdf, 0x25, 0x9b, 0x62, 0x07, 0xfd, 0x0f, 0xd5, 0x76,
0x14, 0xce, 0xf1, 0xa5, 0x57, 0x3b, 0xaa, 0xff, 0x4e, 0xc0, 0x00, 0x69, 0x95,
0x16, 0x59, 0xb8, 0x5f, 0x24, 0x30, 0x0a, 0x25, 0x16, 0x0c, 0xa8, 0x52, 0x2d,
0xc6, 0xe6, 0x72, 0x7e, 0x57, 0xd0, 0x19, 0xd7, 0xe6, 0x36, 0x29, 0xb8, 0xfe,
0x5e, 0x89, 0xe2, 0x5c, 0xc1, 0x5b, 0xeb, 0x3a, 0x64, 0x75, 0x77, 0x55, 0x92,
0x99, 0x28, 0x0b, 0x9b, 0x28, 0xf7, 0x9b, 0x04, 0x09, 0x00, 0x0b, 0xe2, 0x5b,
0xbd, 0x96, 0x40, 0x8b, 0xa3, 0xb4, 0x3c, 0xc4, 0x86, 0x18, 0x4d, 0xd1, 0xc8,
0xe6, 0x25, 0x53, 0xfa, 0x1a, 0xf4, 0x04, 0x0f, 0x60, 0x66, 0x3d, 0xe7, 0xf5,
0xe4, 0x9c, 0x04, 0x38, 0x8e, 0x25, 0x7f, 0x1c, 0xe8, 0x9c, 0x95, 0xda, 0xb4,
0x8a, 0x31, 0x5d, 0x9b, 0x66, 0xb1, 0xb7, 0x62, 0x82, 0x33, 0x87, 0x6f, 0xf2,
0x38, 0x52, 0x30, 0xd0, 0x70, 0xd0, 0x7e, 0x16, 0x66
};
static unsigned char* toUcharPtr(const uint8_t* v) {
return const_cast<unsigned char*>(
static_cast<const unsigned char*>(v));
}
class Pkcs11RsaPssTest : public ::testing::Test {
};
class Pkcs11RsaPssVectorTest : public Pkcs11RsaPssTest {
public:
void Verify(const uint8_t* spki, size_t spki_len, const uint8_t* data,
size_t data_len, const uint8_t* sig, size_t sig_len) {
// Verify data signed with PSS/SHA-1.
SECOidTag hashOid = SEC_OID_SHA1;
CK_MECHANISM_TYPE hashMech = CKM_SHA_1;
CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA1;
// Set up PSS parameters.
unsigned int hLen = HASH_ResultLenByOidTag(hashOid);
CK_RSA_PKCS_PSS_PARAMS rsaPssParams = { hashMech, mgf, hLen };
SECItem params = { siBuffer,
reinterpret_cast<unsigned char*>(&rsaPssParams),
sizeof(rsaPssParams) };
// Import public key.
SECItem spkiItem = { siBuffer, toUcharPtr(spki),
static_cast<unsigned int>(spki_len) };
ScopedCERTSubjectPublicKeyInfo certSpki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
ScopedSECKEYPublicKey pubKey(SECKEY_ExtractPublicKey(certSpki.get()));
// Hash the data.
std::vector<uint8_t> hashBuf(hLen);
SECItem hash = { siBuffer, &hashBuf[0],
static_cast<unsigned int>(hashBuf.size()) };
SECStatus rv = PK11_HashBuf(hashOid, hash.data, toUcharPtr(data),
data_len);
EXPECT_EQ(rv, SECSuccess);
// Verify.
CK_MECHANISM_TYPE mech = CKM_RSA_PKCS_PSS;
SECItem sigItem = { siBuffer, toUcharPtr(sig),
static_cast<unsigned int>(sig_len) };
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, &params, &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, &params, &sig, &data);
EXPECT_EQ(rv, SECSuccess);
// Verify.
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, &params, &sig, &data,
nullptr);
EXPECT_EQ(rv, SECSuccess);
// Verification with modified data must fail.
data.data[0] ^= 0xff;
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, &params, &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, &params, &sig, &data,
nullptr);
EXPECT_EQ(rv, SECFailure);
}
// RSA-PSS test vectors, pss-vect.txt, Example 1.1: A 1024-bit RSA Key Pair
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature1) {
PSS_TEST_VECTOR_VERIFY(kTestVector1Spki, kTestVector1Data, kTestVector1Sig);
}
// RSA-PSS test vectors, pss-vect.txt, Example 10.1: A 2048-bit RSA Key Pair
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature2) {
PSS_TEST_VECTOR_VERIFY(kTestVector2Spki, kTestVector2Data, kTestVector2Sig);
}
} // namespace nss_test

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

@ -25,7 +25,7 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (4) Include "local" platform-dependent assignments (OPTIONAL). # # (4) Include "local" platform-dependent assignments (OPTIONAL). #
####################################################################### #######################################################################
include ../../cmd/platlibs.mk include ../common/gtest.mk
####################################################################### #######################################################################
# (5) Execute "global" rules. (OPTIONAL) # # (5) Execute "global" rules. (OPTIONAL) #
@ -42,19 +42,4 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (7) Execute "local" rules. (OPTIONAL). # # (7) Execute "local" rules. (OPTIONAL). #
####################################################################### #######################################################################
MKPROG = $(CCC)
CFLAGS += -I$(CORE_DEPTH)/lib/ssl CFLAGS += -I$(CORE_DEPTH)/lib/ssl
include ../../cmd/platrules.mk
ifeq (WINNT,$(OS_ARCH))
# -EHsc because gtest has exception handlers
OS_CFLAGS += -EHsc -nologo
# http://www.suodenjoki.dk/us/archive/2010/min-max.htm
OS_CFLAGS += -DNOMINMAX
# Linking to winsock to get htonl
OS_LIBS += Ws2_32.lib
else
CXXFLAGS += -std=c++0x
endif

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

@ -51,9 +51,16 @@ class DataBuffer {
void Assign(const DataBuffer& other) { void Assign(const DataBuffer& other) {
Assign(other.data(), other.len()); Assign(other.data(), other.len());
} }
void Assign(const uint8_t* data, size_t len) { void Assign(const uint8_t* data, size_t len) {
Allocate(len); if (data) {
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len); Allocate(len);
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len);
} else {
assert(len == 0);
data_ = nullptr;
len_ = 0;
}
} }
// Write will do a new allocation and expand the size of the buffer if needed. // Write will do a new allocation and expand the size of the buffer if needed.
@ -166,6 +173,15 @@ inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) {
return stream; return stream;
} }
inline bool operator==(const DataBuffer& a, const DataBuffer& b) {
return (a.empty() && b.empty()) ||
(a.len() == b.len() && 0 == memcmp(a.data(), b.data(), a.len()));
}
inline bool operator!=(const DataBuffer& a, const DataBuffer& b) {
return !(a == b);
}
} // namespace nss_test } // namespace nss_test
#endif #endif

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

@ -15,7 +15,6 @@ CPPSRCS = \
ssl_agent_unittest.cc \ ssl_agent_unittest.cc \
ssl_loopback_unittest.cc \ ssl_loopback_unittest.cc \
ssl_extension_unittest.cc \ ssl_extension_unittest.cc \
ssl_prf_unittest.cc \
ssl_skip_unittest.cc \ ssl_skip_unittest.cc \
ssl_gtest.cc \ ssl_gtest.cc \
test_io.cc \ test_io.cc \

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

@ -609,6 +609,110 @@ TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmConfiguration) {
} }
} }
/*
* Tests for Certificate Transparency (RFC 6962)
*/
// Helper class - stores signed certificate timestamps as provided
// by the relevant callbacks on the client.
class SignedCertificateTimestampsExtractor {
public:
SignedCertificateTimestampsExtractor(TlsAgent& client) {
client.SetAuthCertificateCallback(
[&](TlsAgent& agent, PRBool checksig, PRBool isServer) {
const SECItem *scts = SSL_PeerSignedCertTimestamps(agent.ssl_fd());
ASSERT_TRUE(scts);
auth_timestamps_.reset(new DataBuffer(scts->data, scts->len));
}
);
client.SetHandshakeCallback(
[&](TlsAgent& agent) {
const SECItem *scts = SSL_PeerSignedCertTimestamps(agent.ssl_fd());
ASSERT_TRUE(scts);
handshake_timestamps_.reset(new DataBuffer(scts->data, scts->len));
}
);
}
void assertTimestamps(const DataBuffer& timestamps) {
ASSERT_TRUE(auth_timestamps_);
ASSERT_EQ(timestamps, *auth_timestamps_);
ASSERT_TRUE(handshake_timestamps_);
ASSERT_EQ(timestamps, *handshake_timestamps_);
}
private:
std::unique_ptr<DataBuffer> auth_timestamps_;
std::unique_ptr<DataBuffer> handshake_timestamps_;
};
// Test timestamps extraction during a successful handshake.
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsHandshake) {
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
const DataBuffer timestamps(val, sizeof(val));
server_->StartConnect();
ASSERT_EQ(SECSuccess,
SSL_SetSignedCertTimestamps(server_->ssl_fd(),
&si_timestamps, server_->kea()));
client_->StartConnect();
ASSERT_EQ(SECSuccess,
SSL_OptionSet(client_->ssl_fd(),
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE));
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
Handshake();
CheckConnected();
timestamps_extractor.assertTimestamps(timestamps);
}
// Test SSL_PeerSignedCertTimestamps returning zero-length SECItem
// when the client / the server / both have not enabled the feature.
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveClient) {
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
server_->StartConnect();
ASSERT_EQ(SECSuccess,
SSL_SetSignedCertTimestamps(server_->ssl_fd(),
&si_timestamps, server_->kea()));
client_->StartConnect();
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
Handshake();
CheckConnected();
timestamps_extractor.assertTimestamps(DataBuffer());
}
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveServer) {
server_->StartConnect();
client_->StartConnect();
ASSERT_EQ(SECSuccess,
SSL_OptionSet(client_->ssl_fd(),
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE));
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
Handshake();
CheckConnected();
timestamps_extractor.assertTimestamps(DataBuffer());
}
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveBoth) {
server_->StartConnect();
client_->StartConnect();
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
Handshake();
CheckConnected();
timestamps_extractor.assertTimestamps(DataBuffer());
}
INSTANTIATE_TEST_CASE_P(ExtensionTls10, TlsExtensionTestGeneric, INSTANTIATE_TEST_CASE_P(ExtensionTls10, TlsExtensionTestGeneric,
::testing::Combine( ::testing::Combine(
TlsConnectTestBase::kTlsModesStream, TlsConnectTestBase::kTlsModesStream,

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

@ -40,7 +40,9 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode, SSLKEAType kea
error_code_(0), error_code_(0),
send_ctr_(0), send_ctr_(0),
recv_ctr_(0), recv_ctr_(0),
expected_read_error_(false) { expected_read_error_(false),
handshake_callback_(),
auth_certificate_callback_() {
memset(&info_, 0, sizeof(info_)); memset(&info_, 0, sizeof(info_));
memset(&csinfo_, 0, sizeof(csinfo_)); memset(&csinfo_, 0, sizeof(csinfo_));

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

@ -11,6 +11,7 @@
#include "ssl.h" #include "ssl.h"
#include <iostream> #include <iostream>
#include <functional>
#include "test_io.h" #include "test_io.h"
@ -28,6 +29,16 @@ enum SessionResumptionMode {
RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET
}; };
class TlsAgent;
typedef
std::function<void(TlsAgent& agent, PRBool checksig, PRBool isServer)>
AuthCertificateCallbackFunction;
typedef
std::function<void(TlsAgent& agent)>
HandshakeCallbackFunction;
class TlsAgent : public PollTarget { class TlsAgent : public PollTarget {
public: public:
enum Role { CLIENT, SERVER }; enum Role { CLIENT, SERVER };
@ -94,8 +105,12 @@ class TlsAgent : public PollTarget {
void CheckExtendedMasterSecret(bool expected); void CheckExtendedMasterSecret(bool expected);
void DisableRollbackDetection(); void DisableRollbackDetection();
Role role() const { return role_; }
State state() const { return state_; } State state() const { return state_; }
SSLKEAType kea() const { return kea_; }
const char* state_str() const { return state_str(state()); } const char* state_str() const { return state_str(state()); }
const char* state_str(State state) const { return states[state]; } const char* state_str(State state) const { return states[state]; }
@ -131,6 +146,15 @@ class TlsAgent : public PollTarget {
size_t received_bytes() const { return recv_ctr_; } size_t received_bytes() const { return recv_ctr_; }
int32_t error_code() const { return error_code_; } int32_t error_code() const { return error_code_; }
void SetHandshakeCallback(HandshakeCallbackFunction handshake_callback) {
handshake_callback_ = handshake_callback;
}
void SetAuthCertificateCallback(
AuthCertificateCallbackFunction auth_certificate_callback) {
auth_certificate_callback_ = auth_certificate_callback;
}
private: private:
const static char* states[]; const static char* states[];
@ -148,6 +172,9 @@ class TlsAgent : public PollTarget {
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg); TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
agent->CheckPreliminaryInfo(); agent->CheckPreliminaryInfo();
agent->auth_certificate_hook_called_ = true; agent->auth_certificate_hook_called_ = true;
if (agent->auth_certificate_callback_) {
agent->auth_certificate_callback_(*agent, checksig, isServer);
}
return SECSuccess; return SECSuccess;
} }
@ -157,6 +184,9 @@ class TlsAgent : public PollTarget {
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg); TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
EXPECT_TRUE(agent->expect_client_auth_); EXPECT_TRUE(agent->expect_client_auth_);
EXPECT_TRUE(isServer); EXPECT_TRUE(isServer);
if (agent->auth_certificate_callback_) {
agent->auth_certificate_callback_(*agent, checksig, isServer);
}
return SECSuccess; return SECSuccess;
} }
@ -208,6 +238,9 @@ class TlsAgent : public PollTarget {
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg); TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
agent->CheckPreliminaryInfo(); agent->CheckPreliminaryInfo();
agent->handshake_callback_called_ = true; agent->handshake_callback_called_ = true;
if (agent->handshake_callback_) {
agent->handshake_callback_(*agent);
}
} }
void CheckCallbacks() const; void CheckCallbacks() const;
@ -237,6 +270,8 @@ class TlsAgent : public PollTarget {
size_t send_ctr_; size_t send_ctr_;
size_t recv_ctr_; size_t recv_ctr_;
bool expected_read_error_; bool expected_read_error_;
HandshakeCallbackFunction handshake_callback_;
AuthCertificateCallbackFunction auth_certificate_callback_;
}; };
class TlsAgentTestBase : public ::testing::Test { class TlsAgentTestBase : public ::testing::Test {

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

@ -46,6 +46,10 @@ ifndef NSS_DISABLE_DBM
DBM_SRCDIR = dbm # Add the dbm directory to DIRS. DBM_SRCDIR = dbm # Add the dbm directory to DIRS.
endif endif
ifeq ($(NSS_BUILD_UTIL_ONLY),1)
SYSINIT_SRCDIR=
endif
####################################################################### #######################################################################
# (5) Execute "global" rules. (OPTIONAL) # # (5) Execute "global" rules. (OPTIONAL) #
####################################################################### #######################################################################
@ -62,14 +66,28 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (7) Execute "local" rules. (OPTIONAL). # # (7) Execute "local" rules. (OPTIONAL). #
####################################################################### #######################################################################
ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1) ifeq ($(NSS_BUILD_UTIL_ONLY),1)
# Not included when building nss without softoken UTIL_SRCDIR = util
UTIL_SRCDIR = FREEBL_SRCDIR =
FREEBL_SRCDIR = SOFTOKEN_SRCDIR =
SOFTOKEN_SRCDIR =
else else
# default is to include all ifeq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
UTIL_SRCDIR = util UTIL_SRCDIR =
FREEBL_SRCDIR = freebl FREEBL_SRCDIR = freebl
SOFTOKEN_SRCDIR = softoken SOFTOKEN_SRCDIR = softoken
else
ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
# Not included when building nss without softoken
# This build type uses the build results of the prior
# NSS_BUILD_UTIL_ONLY and NSS_BUILD_SOFTOKEN_ONLY builds
UTIL_SRCDIR =
FREEBL_SRCDIR =
SOFTOKEN_SRCDIR =
else
# default is to include all
UTIL_SRCDIR = util
FREEBL_SRCDIR = freebl
SOFTOKEN_SRCDIR = softoken
endif
endif
endif endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -32,7 +32,7 @@ typedef struct nssArenaMarkStr nssArenaMark;
#ifdef DEBUG #ifdef DEBUG
/* /*
* ARENA_THREADMARK * ARENA_THREADMARK
* *
* Optionally, this arena implementation can be compiled with some * Optionally, this arena implementation can be compiled with some
* runtime checking enabled, which will catch the situation where * runtime checking enabled, which will catch the situation where
* one thread "marks" the arena, another thread allocates memory, * one thread "marks" the arena, another thread allocates memory,
@ -68,14 +68,13 @@ typedef struct nssArenaMarkStr nssArenaMark;
typedef struct nssListStr nssList; typedef struct nssListStr nssList;
typedef struct nssListIteratorStr nssListIterator; typedef struct nssListIteratorStr nssListIterator;
typedef PRBool (* nssListCompareFunc)(void *a, void *b); typedef PRBool (*nssListCompareFunc)(void *a, void *b);
typedef PRIntn (* nssListSortFunc)(void *a, void *b); typedef PRIntn (*nssListSortFunc)(void *a, void *b);
typedef void (* nssListElementDestructorFunc)(void *el); typedef void (*nssListElementDestructorFunc)(void *el);
typedef struct nssHashStr nssHash; typedef struct nssHashStr nssHash;
typedef void (PR_CALLBACK *nssHashIterator)(const void *key, typedef void(PR_CALLBACK *nssHashIterator)(const void *key, void *value,
void *value, void *arg);
void *arg);
/* /*
* nssPointerTracker * nssPointerTracker
@ -89,9 +88,9 @@ typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
#ifdef DEBUG #ifdef DEBUG
struct nssPointerTrackerStr { struct nssPointerTrackerStr {
PRCallOnceType once; PRCallOnceType once;
PZLock *lock; PZLock *lock;
PLHashTable *table; PLHashTable *table;
}; };
typedef struct nssPointerTrackerStr nssPointerTracker; typedef struct nssPointerTrackerStr nssPointerTracker;
#endif /* DEBUG */ #endif /* DEBUG */
@ -107,16 +106,16 @@ typedef struct nssPointerTrackerStr nssPointerTracker;
*/ */
enum nssStringTypeEnum { enum nssStringTypeEnum {
nssStringType_DirectoryString, nssStringType_DirectoryString,
nssStringType_TeletexString, /* Not "teletext" with trailing 't' */ nssStringType_TeletexString, /* Not "teletext" with trailing 't' */
nssStringType_PrintableString, nssStringType_PrintableString,
nssStringType_UniversalString, nssStringType_UniversalString,
nssStringType_BMPString, nssStringType_BMPString,
nssStringType_UTF8String, nssStringType_UTF8String,
nssStringType_PHGString, nssStringType_PHGString,
nssStringType_GeneralString, nssStringType_GeneralString,
nssStringType_Unknown = -1 nssStringType_Unknown = -1
}; };
typedef enum nssStringTypeEnum nssStringType; typedef enum nssStringTypeEnum nssStringType;

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

@ -5,13 +5,13 @@
/* /*
* error.c * error.c
* *
* This file contains the code implementing the per-thread error * This file contains the code implementing the per-thread error
* stacks upon which most NSS routines report their errors. * stacks upon which most NSS routines report their errors.
*/ */
#ifndef BASE_H #ifndef BASE_H
#include "base.h" #include "base.h"
#endif /* BASE_H */ #endif /* BASE_H */
#include <limits.h> /* for UINT_MAX */ #include <limits.h> /* for UINT_MAX */
#include <string.h> /* for memmove */ #include <string.h> /* for memmove */
@ -25,13 +25,13 @@
*/ */
struct stack_header_str { struct stack_header_str {
PRUint16 space; PRUint16 space;
PRUint16 count; PRUint16 count;
}; };
struct error_stack_str { struct error_stack_str {
struct stack_header_str header; struct stack_header_str header;
PRInt32 stack[1]; PRInt32 stack[1];
}; };
typedef struct error_stack_str error_stack; typedef struct error_stack_str error_stack;
@ -62,9 +62,9 @@ static PRCallOnceType error_call_once;
* This is the once-called callback. * This is the once-called callback.
*/ */
static PRStatus static PRStatus
error_once_function ( void) error_once_function(void)
{ {
return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free); return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
} }
/* /*
@ -76,48 +76,50 @@ error_once_function ( void)
*/ */
static error_stack * static error_stack *
error_get_my_stack ( void) error_get_my_stack(void)
{ {
PRStatus st; PRStatus st;
error_stack *rv; error_stack *rv;
PRUintn new_size; PRUintn new_size;
PRUint32 new_bytes; PRUint32 new_bytes;
error_stack *new_stack; error_stack *new_stack;
if( INVALID_TPD_INDEX == error_stack_index ) { if (INVALID_TPD_INDEX == error_stack_index) {
st = PR_CallOnce(&error_call_once, error_once_function); st = PR_CallOnce(&error_call_once, error_once_function);
if( PR_SUCCESS != st ) { if (PR_SUCCESS != st) {
return (error_stack *)NULL; return (error_stack *)NULL;
}
} }
}
rv = (error_stack *)PR_GetThreadPrivate(error_stack_index); rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
if( (error_stack *)NULL == rv ) { if ((error_stack *)NULL == rv) {
/* Doesn't exist; create one */ /* Doesn't exist; create one */
new_size = 16; new_size = 16;
} else if( rv->header.count == rv->header.space && }
rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) { else if (rv->header.count == rv->header.space &&
/* Too small, expand it */ rv->header.count < NSS_MAX_ERROR_STACK_COUNT) {
new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT); /* Too small, expand it */
} else { new_size = PR_MIN(rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
/* Okay, return it */ }
return rv; else {
} /* Okay, return it */
return rv;
new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
/* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
new_stack = PR_Calloc(1, new_bytes);
if( (error_stack *)NULL != new_stack ) {
if( (error_stack *)NULL != rv ) {
(void)nsslibc_memcpy(new_stack,rv,rv->header.space);
} }
new_stack->header.space = new_size;
}
/* Set the value, whether or not the allocation worked */ new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
PR_SetThreadPrivate(error_stack_index, new_stack); /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
return new_stack; new_stack = PR_Calloc(1, new_bytes);
if ((error_stack *)NULL != new_stack) {
if ((error_stack *)NULL != rv) {
(void)nsslibc_memcpy(new_stack, rv, rv->header.space);
}
new_stack->header.space = new_size;
}
/* Set the value, whether or not the allocation worked */
PR_SetThreadPrivate(error_stack_index, new_stack);
return new_stack;
} }
/* /*
@ -151,19 +153,19 @@ error_get_my_stack ( void)
*/ */
NSS_IMPLEMENT PRInt32 NSS_IMPLEMENT PRInt32
NSS_GetError ( void) NSS_GetError(void)
{ {
error_stack *es = error_get_my_stack(); error_stack *es = error_get_my_stack();
if( (error_stack *)NULL == es ) { if ((error_stack *)NULL == es) {
return NSS_ERROR_NO_MEMORY; /* Good guess! */ return NSS_ERROR_NO_MEMORY; /* Good guess! */
} }
if( 0 == es->header.count ) { if (0 == es->header.count) {
return 0; return 0;
} }
return es->stack[ es->header.count-1 ]; return es->stack[es->header.count - 1];
} }
/* /*
@ -174,7 +176,7 @@ NSS_GetError ( void)
* library routine called by the same thread calling this routine. * library routine called by the same thread calling this routine.
* NOTE: the caller DOES NOT OWN the memory pointed to by the return * NOTE: the caller DOES NOT OWN the memory pointed to by the return
* value. The pointer will remain valid until the calling thread * value. The pointer will remain valid until the calling thread
* calls another NSS routine. The lowest-level (most specific) error * calls another NSS routine. The lowest-level (most specific) error
* is first in the array, and the highest-level is last. The array is * is first in the array, and the highest-level is last. The array is
* zero-terminated. This routine may return NULL upon error; this * zero-terminated. This routine may return NULL upon error; this
* indicates a low-memory situation. * indicates a low-memory situation.
@ -185,52 +187,53 @@ NSS_GetError ( void)
*/ */
NSS_IMPLEMENT PRInt32 * NSS_IMPLEMENT PRInt32 *
NSS_GetErrorStack ( void) NSS_GetErrorStack(void)
{ {
error_stack *es = error_get_my_stack(); error_stack *es = error_get_my_stack();
if( (error_stack *)NULL == es ) { if ((error_stack *)NULL == es) {
return (PRInt32 *)NULL; return (PRInt32 *)NULL;
} }
/* Make sure it's terminated */ /* Make sure it's terminated */
es->stack[ es->header.count ] = 0; es->stack[es->header.count] = 0;
return es->stack; return es->stack;
} }
/* /*
* nss_SetError * nss_SetError
* *
* This routine places a new error code on the top of the calling * This routine places a new error code on the top of the calling
* thread's error stack. Calling this routine wiht an error code * thread's error stack. Calling this routine wiht an error code
* of zero will clear the error stack. * of zero will clear the error stack.
*/ */
NSS_IMPLEMENT void NSS_IMPLEMENT void
nss_SetError ( PRUint32 error) nss_SetError(PRUint32 error)
{ {
error_stack *es; error_stack *es;
if( 0 == error ) { if (0 == error) {
nss_ClearErrorStack(); nss_ClearErrorStack();
return;
}
es = error_get_my_stack();
if ((error_stack *)NULL == es) {
/* Oh, well. */
return;
}
if (es->header.count < es->header.space) {
es->stack[es->header.count++] = error;
}
else {
memmove(es->stack, es->stack + 1,
(es->header.space - 1) * (sizeof es->stack[0]));
es->stack[es->header.space - 1] = error;
}
return; return;
}
es = error_get_my_stack();
if( (error_stack *)NULL == es ) {
/* Oh, well. */
return;
}
if (es->header.count < es->header.space) {
es->stack[ es->header.count++ ] = error;
} else {
memmove(es->stack, es->stack + 1,
(es->header.space - 1) * (sizeof es->stack[0]));
es->stack[ es->header.space - 1 ] = error;
}
return;
} }
/* /*
@ -240,17 +243,17 @@ nss_SetError ( PRUint32 error)
*/ */
NSS_IMPLEMENT void NSS_IMPLEMENT void
nss_ClearErrorStack ( void) nss_ClearErrorStack(void)
{ {
error_stack *es = error_get_my_stack(); error_stack *es = error_get_my_stack();
if( (error_stack *)NULL == es ) { if ((error_stack *)NULL == es) {
/* Oh, well. */ /* Oh, well. */
return; return;
} }
es->header.count = 0; es->header.count = 0;
es->stack[0] = 0; es->stack[0] = 0;
return; return;
} }
/* /*
@ -260,10 +263,10 @@ nss_ClearErrorStack ( void)
*/ */
NSS_IMPLEMENT void NSS_IMPLEMENT void
nss_DestroyErrorStack ( void) nss_DestroyErrorStack(void)
{ {
if( INVALID_TPD_INDEX != error_stack_index ) { if (INVALID_TPD_INDEX != error_stack_index) {
PR_SetThreadPrivate(error_stack_index, NULL); PR_SetThreadPrivate(error_stack_index, NULL);
} }
return; return;
} }

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

@ -12,6 +12,8 @@
#include "nssbaset.h" #include "nssbaset.h"
#endif /* NSSBASET_H */ #endif /* NSSBASET_H */
/* clang-format off */
const NSSError NSS_ERROR_NO_ERROR = 0; const NSSError NSS_ERROR_NO_ERROR = 0;
const NSSError NSS_ERROR_INTERNAL_ERROR = 1; const NSSError NSS_ERROR_INTERNAL_ERROR = 1;
const NSSError NSS_ERROR_NO_MEMORY = 2; const NSSError NSS_ERROR_NO_MEMORY = 2;
@ -60,3 +62,4 @@ const NSSError NSS_ERROR_ALREADY_INITIALIZED = 37;
const NSSError NSS_ERROR_PKCS11 = 38; const NSSError NSS_ERROR_PKCS11 = 38;
/* clang-format on */

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

@ -32,48 +32,42 @@
*/ */
struct nssHashStr { struct nssHashStr {
NSSArena *arena; NSSArena *arena;
PRBool i_alloced_arena; PRBool i_alloced_arena;
PRLock *mutex; PRLock *mutex;
/* /*
* The invariant that mutex protects is: * The invariant that mutex protects is:
* The count accurately reflects the hashtable state. * The count accurately reflects the hashtable state.
*/ */
PLHashTable *plHashTable; PLHashTable *plHashTable;
PRUint32 count; PRUint32 count;
}; };
static PLHashNumber static PLHashNumber
nss_identity_hash nss_identity_hash(const void *key)
(
const void *key
)
{ {
return (PLHashNumber)((char *)key - (char *)NULL); return (PLHashNumber)((char *)key - (char *)NULL);
} }
static PLHashNumber static PLHashNumber
nss_item_hash nss_item_hash(const void *key)
(
const void *key
)
{ {
unsigned int i; unsigned int i;
PLHashNumber h; PLHashNumber h;
NSSItem *it = (NSSItem *)key; NSSItem *it = (NSSItem *)key;
h = 0; h = 0;
for (i=0; i<it->size; i++) for (i = 0; i < it->size; i++)
h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i]; h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i];
return h; return h;
} }
static int static int
nss_compare_items(const void *v1, const void *v2) nss_compare_items(const void *v1, const void *v2)
{ {
PRStatus ignore; PRStatus ignore;
return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore); return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore);
} }
/* /*
@ -81,60 +75,55 @@ nss_compare_items(const void *v1, const void *v2)
* *
*/ */
NSS_IMPLEMENT nssHash * NSS_IMPLEMENT nssHash *
nssHash_Create nssHash_Create(NSSArena *arenaOpt, PRUint32 numBuckets, PLHashFunction keyHash,
( PLHashComparator keyCompare, PLHashComparator valueCompare)
NSSArena *arenaOpt,
PRUint32 numBuckets,
PLHashFunction keyHash,
PLHashComparator keyCompare,
PLHashComparator valueCompare
)
{ {
nssHash *rv; nssHash *rv;
NSSArena *arena; NSSArena *arena;
PRBool i_alloced; PRBool i_alloced;
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { if (arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return (nssHash *)NULL; return (nssHash *)NULL;
} }
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
if (arenaOpt) { if (arenaOpt) {
arena = arenaOpt; arena = arenaOpt;
i_alloced = PR_FALSE; i_alloced = PR_FALSE;
} else { }
arena = nssArena_Create(); else {
i_alloced = PR_TRUE; arena = nssArena_Create();
} i_alloced = PR_TRUE;
}
rv = nss_ZNEW(arena, nssHash); rv = nss_ZNEW(arena, nssHash);
if( (nssHash *)NULL == rv ) { if ((nssHash *)NULL == rv) {
goto loser; goto loser;
} }
rv->mutex = PZ_NewLock(nssILockOther); rv->mutex = PZ_NewLock(nssILockOther);
if( (PZLock *)NULL == rv->mutex ) { if ((PZLock *)NULL == rv->mutex) {
goto loser; goto loser;
} }
rv->plHashTable = PL_NewHashTable(numBuckets, rv->plHashTable =
keyHash, keyCompare, valueCompare, PL_NewHashTable(numBuckets, keyHash, keyCompare, valueCompare,
&nssArenaHashAllocOps, arena); &nssArenaHashAllocOps, arena);
if( (PLHashTable *)NULL == rv->plHashTable ) { if ((PLHashTable *)NULL == rv->plHashTable) {
(void)PZ_DestroyLock(rv->mutex); (void)PZ_DestroyLock(rv->mutex);
goto loser; goto loser;
} }
rv->count = 0; rv->count = 0;
rv->arena = arena; rv->arena = arena;
rv->i_alloced_arena = i_alloced; rv->i_alloced_arena = i_alloced;
return rv; return rv;
loser: loser:
(void)nss_ZFreeIf(rv); (void)nss_ZFreeIf(rv);
return (nssHash *)NULL; return (nssHash *)NULL;
} }
/* /*
@ -142,14 +131,10 @@ loser:
* *
*/ */
NSS_IMPLEMENT nssHash * NSS_IMPLEMENT nssHash *
nssHash_CreatePointer nssHash_CreatePointer(NSSArena *arenaOpt, PRUint32 numBuckets)
(
NSSArena *arenaOpt,
PRUint32 numBuckets
)
{ {
return nssHash_Create(arenaOpt, numBuckets, return nssHash_Create(arenaOpt, numBuckets, nss_identity_hash,
nss_identity_hash, PL_CompareValues, PL_CompareValues); PL_CompareValues, PL_CompareValues);
} }
/* /*
@ -157,14 +142,10 @@ nssHash_CreatePointer
* *
*/ */
NSS_IMPLEMENT nssHash * NSS_IMPLEMENT nssHash *
nssHash_CreateString nssHash_CreateString(NSSArena *arenaOpt, PRUint32 numBuckets)
(
NSSArena *arenaOpt,
PRUint32 numBuckets
)
{ {
return nssHash_Create(arenaOpt, numBuckets, return nssHash_Create(arenaOpt, numBuckets, PL_HashString,
PL_HashString, PL_CompareStrings, PL_CompareStrings); PL_CompareStrings, PL_CompareStrings);
} }
/* /*
@ -172,14 +153,10 @@ nssHash_CreateString
* *
*/ */
NSS_IMPLEMENT nssHash * NSS_IMPLEMENT nssHash *
nssHash_CreateItem nssHash_CreateItem(NSSArena *arenaOpt, PRUint32 numBuckets)
(
NSSArena *arenaOpt,
PRUint32 numBuckets
)
{ {
return nssHash_Create(arenaOpt, numBuckets, return nssHash_Create(arenaOpt, numBuckets, nss_item_hash,
nss_item_hash, nss_compare_items, PL_CompareValues); nss_compare_items, PL_CompareValues);
} }
/* /*
@ -187,18 +164,16 @@ nssHash_CreateItem
* *
*/ */
NSS_IMPLEMENT void NSS_IMPLEMENT void
nssHash_Destroy nssHash_Destroy(nssHash *hash)
(
nssHash *hash
)
{ {
(void)PZ_DestroyLock(hash->mutex); (void)PZ_DestroyLock(hash->mutex);
PL_HashTableDestroy(hash->plHashTable); PL_HashTableDestroy(hash->plHashTable);
if (hash->i_alloced_arena) { if (hash->i_alloced_arena) {
nssArena_Destroy(hash->arena); nssArena_Destroy(hash->arena);
} else { }
nss_ZFreeIf(hash); else {
} nss_ZFreeIf(hash);
}
} }
/* /*
@ -206,31 +181,28 @@ nssHash_Destroy
* *
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssHash_Add nssHash_Add(nssHash *hash, const void *key, const void *value)
(
nssHash *hash,
const void *key,
const void *value
)
{ {
PRStatus error = PR_FAILURE; PRStatus error = PR_FAILURE;
PLHashEntry *he; PLHashEntry *he;
PZ_Lock(hash->mutex); PZ_Lock(hash->mutex);
he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
if( (PLHashEntry *)NULL == he ) {
nss_SetError(NSS_ERROR_NO_MEMORY);
} else if (he->value != value) {
nss_SetError(NSS_ERROR_HASH_COLLISION);
} else {
hash->count++;
error = PR_SUCCESS;
}
(void)PZ_Unlock(hash->mutex); he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
if ((PLHashEntry *)NULL == he) {
nss_SetError(NSS_ERROR_NO_MEMORY);
}
else if (he->value != value) {
nss_SetError(NSS_ERROR_HASH_COLLISION);
}
else {
hash->count++;
error = PR_SUCCESS;
}
return error; (void)PZ_Unlock(hash->mutex);
return error;
} }
/* /*
@ -238,23 +210,19 @@ nssHash_Add
* *
*/ */
NSS_IMPLEMENT void NSS_IMPLEMENT void
nssHash_Remove nssHash_Remove(nssHash *hash, const void *it)
(
nssHash *hash,
const void *it
)
{ {
PRBool found; PRBool found;
PZ_Lock(hash->mutex); PZ_Lock(hash->mutex);
found = PL_HashTableRemove(hash->plHashTable, it); found = PL_HashTableRemove(hash->plHashTable, it);
if( found ) { if (found) {
hash->count--; hash->count--;
} }
(void)PZ_Unlock(hash->mutex); (void)PZ_Unlock(hash->mutex);
return; return;
} }
/* /*
@ -262,20 +230,17 @@ nssHash_Remove
* *
*/ */
NSS_IMPLEMENT PRUint32 NSS_IMPLEMENT PRUint32
nssHash_Count nssHash_Count(nssHash *hash)
(
nssHash *hash
)
{ {
PRUint32 count; PRUint32 count;
PZ_Lock(hash->mutex); PZ_Lock(hash->mutex);
count = hash->count; count = hash->count;
(void)PZ_Unlock(hash->mutex); (void)PZ_Unlock(hash->mutex);
return count; return count;
} }
/* /*
@ -283,25 +248,22 @@ nssHash_Count
* *
*/ */
NSS_IMPLEMENT PRBool NSS_IMPLEMENT PRBool
nssHash_Exists nssHash_Exists(nssHash *hash, const void *it)
(
nssHash *hash,
const void *it
)
{ {
void *value; void *value;
PZ_Lock(hash->mutex); PZ_Lock(hash->mutex);
value = PL_HashTableLookup(hash->plHashTable, it); value = PL_HashTableLookup(hash->plHashTable, it);
(void)PZ_Unlock(hash->mutex); (void)PZ_Unlock(hash->mutex);
if( (void *)NULL == value ) { if ((void *)NULL == value) {
return PR_FALSE; return PR_FALSE;
} else { }
return PR_TRUE; else {
} return PR_TRUE;
}
} }
/* /*
@ -309,39 +271,30 @@ nssHash_Exists
* *
*/ */
NSS_IMPLEMENT void * NSS_IMPLEMENT void *
nssHash_Lookup nssHash_Lookup(nssHash *hash, const void *it)
(
nssHash *hash,
const void *it
)
{ {
void *rv; void *rv;
PZ_Lock(hash->mutex); PZ_Lock(hash->mutex);
rv = PL_HashTableLookup(hash->plHashTable, it); rv = PL_HashTableLookup(hash->plHashTable, it);
(void)PZ_Unlock(hash->mutex); (void)PZ_Unlock(hash->mutex);
return rv; return rv;
} }
struct arg_str { struct arg_str {
nssHashIterator fcn; nssHashIterator fcn;
void *closure; void *closure;
}; };
static PRIntn static PRIntn
nss_hash_enumerator nss_hash_enumerator(PLHashEntry *he, PRIntn index, void *arg)
(
PLHashEntry *he,
PRIntn index,
void *arg
)
{ {
struct arg_str *as = (struct arg_str *)arg; struct arg_str *as = (struct arg_str *)arg;
as->fcn(he->key, he->value, as->closure); as->fcn(he->key, he->value, as->closure);
return HT_ENUMERATE_NEXT; return HT_ENUMERATE_NEXT;
} }
/* /*
@ -350,22 +303,17 @@ nss_hash_enumerator
* NOTE that the iteration function will be called with the hashtable locked. * NOTE that the iteration function will be called with the hashtable locked.
*/ */
NSS_IMPLEMENT void NSS_IMPLEMENT void
nssHash_Iterate nssHash_Iterate(nssHash *hash, nssHashIterator fcn, void *closure)
(
nssHash *hash,
nssHashIterator fcn,
void *closure
)
{ {
struct arg_str as; struct arg_str as;
as.fcn = fcn; as.fcn = fcn;
as.closure = closure; as.closure = closure;
PZ_Lock(hash->mutex); PZ_Lock(hash->mutex);
PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as); PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as);
(void)PZ_Unlock(hash->mutex); (void)PZ_Unlock(hash->mutex);
return; return;
} }

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

@ -12,73 +12,53 @@
#include "base.h" #include "base.h"
#endif /* BASE_H */ #endif /* BASE_H */
static void * PR_CALLBACK static void *PR_CALLBACK
nss_arena_hash_alloc_table nss_arena_hash_alloc_table(void *pool, PRSize size)
(
void *pool,
PRSize size
)
{ {
NSSArena *arena = (NSSArena *)NULL; NSSArena *arena = (NSSArena *)NULL;
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( (void *)NULL != arena ) { if ((void *)NULL != arena) {
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
return (void *)NULL; return (void *)NULL;
}
} }
}
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
return nss_ZAlloc(arena, size); return nss_ZAlloc(arena, size);
} }
static void PR_CALLBACK static void PR_CALLBACK
nss_arena_hash_free_table nss_arena_hash_free_table(void *pool, void *item)
(
void *pool,
void *item
)
{ {
(void)nss_ZFreeIf(item); (void)nss_ZFreeIf(item);
} }
static PLHashEntry * PR_CALLBACK static PLHashEntry *PR_CALLBACK
nss_arena_hash_alloc_entry nss_arena_hash_alloc_entry(void *pool, const void *key)
(
void *pool,
const void *key
)
{ {
NSSArena *arena = NULL; NSSArena *arena = NULL;
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( (void *)NULL != arena ) { if ((void *)NULL != arena) {
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
return (void *)NULL; return (void *)NULL;
}
} }
}
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
return nss_ZNEW(arena, PLHashEntry); return nss_ZNEW(arena, PLHashEntry);
} }
static void PR_CALLBACK static void PR_CALLBACK
nss_arena_hash_free_entry nss_arena_hash_free_entry(void *pool, PLHashEntry *he, PRUintn flag)
(
void *pool,
PLHashEntry *he,
PRUintn flag
)
{ {
if( HT_FREE_ENTRY == flag ) { if (HT_FREE_ENTRY == flag) {
(void)nss_ZFreeIf(he); (void)nss_ZFreeIf(he);
} }
} }
NSS_IMPLEMENT_DATA PLHashAllocOps NSS_IMPLEMENT_DATA PLHashAllocOps nssArenaHashAllocOps = {
nssArenaHashAllocOps = { nss_arena_hash_alloc_table, nss_arena_hash_free_table,
nss_arena_hash_alloc_table, nss_arena_hash_alloc_entry, nss_arena_hash_free_entry
nss_arena_hash_free_table,
nss_arena_hash_alloc_entry,
nss_arena_hash_free_entry
}; };

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

@ -22,78 +22,70 @@
* NSS_ERROR_NO_MEMORY * NSS_ERROR_NO_MEMORY
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
* NSS_ERROR_INVALID_POINTER * NSS_ERROR_INVALID_POINTER
* *
* Return value: * Return value:
* A pointer to an NSSItem upon success * A pointer to an NSSItem upon success
* NULL upon failure * NULL upon failure
*/ */
NSS_IMPLEMENT NSSItem * NSS_IMPLEMENT NSSItem *
nssItem_Create nssItem_Create(NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length,
( const void *data)
NSSArena *arenaOpt,
NSSItem *rvOpt,
PRUint32 length,
const void *data
)
{ {
NSSItem *rv = (NSSItem *)NULL; NSSItem *rv = (NSSItem *)NULL;
#ifdef DEBUG #ifdef DEBUG
if( (NSSArena *)NULL != arenaOpt ) { if ((NSSArena *)NULL != arenaOpt) {
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
return (NSSItem *)NULL; return (NSSItem *)NULL;
}
} }
}
if( (const void *)NULL == data ) { if ((const void *)NULL == data) {
if( length > 0 ) { if (length > 0) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return (NSSItem *)NULL; return (NSSItem *)NULL;
}
} }
}
#endif /* DEBUG */ #endif /* DEBUG */
if( (NSSItem *)NULL == rvOpt ) { if ((NSSItem *)NULL == rvOpt) {
rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem); rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
if( (NSSItem *)NULL == rv ) { if ((NSSItem *)NULL == rv) {
goto loser; goto loser;
}
}
else {
rv = rvOpt;
} }
} else {
rv = rvOpt;
}
rv->size = length; rv->size = length;
rv->data = nss_ZAlloc(arenaOpt, length); rv->data = nss_ZAlloc(arenaOpt, length);
if( (void *)NULL == rv->data ) { if ((void *)NULL == rv->data) {
goto loser; goto loser;
} }
if( length > 0 ) { if (length > 0) {
(void)nsslibc_memcpy(rv->data, data, length); (void)nsslibc_memcpy(rv->data, data, length);
} }
return rv; return rv;
loser: loser:
if( rv != rvOpt ) { if (rv != rvOpt) {
nss_ZFreeIf(rv); nss_ZFreeIf(rv);
} }
return (NSSItem *)NULL; return (NSSItem *)NULL;
} }
NSS_IMPLEMENT void NSS_IMPLEMENT void
nssItem_Destroy nssItem_Destroy(NSSItem *item)
(
NSSItem *item
)
{ {
nss_ClearErrorStack(); nss_ClearErrorStack();
nss_ZFreeIf(item->data);
nss_ZFreeIf(item);
nss_ZFreeIf(item->data);
nss_ZFreeIf(item);
} }
/* /*
@ -106,34 +98,29 @@ nssItem_Destroy
* NSS_ERROR_NO_MEMORY * NSS_ERROR_NO_MEMORY
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
* NSS_ERROR_INVALID_ITEM * NSS_ERROR_INVALID_ITEM
* *
* Return value: * Return value:
* A pointer to an NSSItem upon success * A pointer to an NSSItem upon success
* NULL upon failure * NULL upon failure
*/ */
NSS_IMPLEMENT NSSItem * NSS_IMPLEMENT NSSItem *
nssItem_Duplicate nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt)
(
NSSItem *obj,
NSSArena *arenaOpt,
NSSItem *rvOpt
)
{ {
#ifdef DEBUG #ifdef DEBUG
if( (NSSArena *)NULL != arenaOpt ) { if ((NSSArena *)NULL != arenaOpt) {
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
return (NSSItem *)NULL; return (NSSItem *)NULL;
}
} }
}
if( (NSSItem *)NULL == obj ) { if ((NSSItem *)NULL == obj) {
nss_SetError(NSS_ERROR_INVALID_ITEM); nss_SetError(NSS_ERROR_INVALID_ITEM);
return (NSSItem *)NULL; return (NSSItem *)NULL;
} }
#endif /* DEBUG */ #endif /* DEBUG */
return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data); return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
} }
#ifdef DEBUG #ifdef DEBUG
@ -151,18 +138,15 @@ nssItem_Duplicate
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssItem_verifyPointer nssItem_verifyPointer(const NSSItem *item)
(
const NSSItem *item
)
{ {
if( ((const NSSItem *)NULL == item) || if (((const NSSItem *)NULL == item) ||
(((void *)NULL == item->data) && (item->size > 0)) ) { (((void *)NULL == item->data) && (item->size > 0))) {
nss_SetError(NSS_ERROR_INVALID_ITEM); nss_SetError(NSS_ERROR_INVALID_ITEM);
return PR_FAILURE; return PR_FAILURE;
} }
return PR_SUCCESS; return PR_SUCCESS;
} }
#endif /* DEBUG */ #endif /* DEBUG */
@ -181,28 +165,23 @@ nssItem_verifyPointer
*/ */
NSS_IMPLEMENT PRBool NSS_IMPLEMENT PRBool
nssItem_Equal nssItem_Equal(const NSSItem *one, const NSSItem *two, PRStatus *statusOpt)
(
const NSSItem *one,
const NSSItem *two,
PRStatus *statusOpt
)
{ {
if( (PRStatus *)NULL != statusOpt ) { if ((PRStatus *)NULL != statusOpt) {
*statusOpt = PR_SUCCESS; *statusOpt = PR_SUCCESS;
} }
if( ((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two) ) { if (((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two)) {
return PR_TRUE; return PR_TRUE;
} }
if( ((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two) ) { if (((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two)) {
return PR_FALSE; return PR_FALSE;
} }
if( one->size != two->size ) { if (one->size != two->size) {
return PR_FALSE; return PR_FALSE;
} }
return nsslibc_memequal(one->data, two->data, one->size, statusOpt); return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
} }

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

@ -5,10 +5,10 @@
/* /*
* libc.c * libc.c
* *
* This file contains our wrappers/reimplementations for "standard" * This file contains our wrappers/reimplementations for "standard"
* libc functions. Things like "memcpy." We add to this as we need * libc functions. Things like "memcpy." We add to this as we need
* it. Oh, and let's keep it in alphabetical order, should it ever * it. Oh, and let's keep it in alphabetical order, should it ever
* get large. Most string/character stuff should be in utf8.c, not * get large. Most string/character stuff should be in utf8.c, not
* here. This file (and maybe utf8.c) should be the only ones in * here. This file (and maybe utf8.c) should be the only ones in
* NSS to include files with angle brackets. * NSS to include files with angle brackets.
*/ */
@ -38,21 +38,16 @@
*/ */
NSS_IMPLEMENT void * NSS_IMPLEMENT void *
nsslibc_memcpy nsslibc_memcpy(void *dest, const void *source, PRUint32 n)
(
void *dest,
const void *source,
PRUint32 n
)
{ {
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( ((void *)NULL == dest) || ((const void *)NULL == source) ) { if (((void *)NULL == dest) || ((const void *)NULL == source)) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return (void *)NULL; return (void *)NULL;
} }
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
return memcpy(dest, source, (size_t)n); return memcpy(dest, source, (size_t)n);
} }
/* /*
@ -67,21 +62,16 @@ nsslibc_memcpy
*/ */
NSS_IMPLEMENT void * NSS_IMPLEMENT void *
nsslibc_memset nsslibc_memset(void *dest, PRUint8 byte, PRUint32 n)
(
void *dest,
PRUint8 byte,
PRUint32 n
)
{ {
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( ((void *)NULL == dest) ) { if (((void *)NULL == dest)) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return (void *)NULL; return (void *)NULL;
} }
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
return memset(dest, (int)byte, (size_t)n); return memset(dest, (int)byte, (size_t)n);
} }
/* /*
@ -97,33 +87,29 @@ nsslibc_memset
*/ */
NSS_IMPLEMENT PRBool NSS_IMPLEMENT PRBool
nsslibc_memequal nsslibc_memequal(const void *a, const void *b, PRUint32 len,
( PRStatus *statusOpt)
const void *a,
const void *b,
PRUint32 len,
PRStatus *statusOpt
)
{ {
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( (((void *)NULL == a) || ((void *)NULL == b)) ) { if ((((void *)NULL == a) || ((void *)NULL == b))) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
if( (PRStatus *)NULL != statusOpt ) { if ((PRStatus *)NULL != statusOpt) {
*statusOpt = PR_FAILURE; *statusOpt = PR_FAILURE;
}
return PR_FALSE;
} }
return PR_FALSE;
}
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
if( (PRStatus *)NULL != statusOpt ) { if ((PRStatus *)NULL != statusOpt) {
*statusOpt = PR_SUCCESS; *statusOpt = PR_SUCCESS;
} }
if( 0 == memcmp(a, b, len) ) { if (0 == memcmp(a, b, len)) {
return PR_TRUE; return PR_TRUE;
} else { }
return PR_FALSE; else {
} return PR_FALSE;
}
} }
/* /*
@ -131,32 +117,26 @@ nsslibc_memequal
*/ */
NSS_IMPLEMENT PRInt32 NSS_IMPLEMENT PRInt32
nsslibc_memcmp nsslibc_memcmp(const void *a, const void *b, PRUint32 len, PRStatus *statusOpt)
(
const void *a,
const void *b,
PRUint32 len,
PRStatus *statusOpt
)
{ {
int v; int v;
#ifdef NSSDEBUG #ifdef NSSDEBUG
if( (((void *)NULL == a) || ((void *)NULL == b)) ) { if ((((void *)NULL == a) || ((void *)NULL == b))) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
if( (PRStatus *)NULL != statusOpt ) { if ((PRStatus *)NULL != statusOpt) {
*statusOpt = PR_FAILURE; *statusOpt = PR_FAILURE;
}
return -2;
} }
return -2;
}
#endif /* NSSDEBUG */ #endif /* NSSDEBUG */
if( (PRStatus *)NULL != statusOpt ) { if ((PRStatus *)NULL != statusOpt) {
*statusOpt = PR_SUCCESS; *statusOpt = PR_SUCCESS;
} }
v = memcmp(a, b, len); v = memcmp(a, b, len);
return (PRInt32)v; return (PRInt32)v;
} }
/* /*

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

@ -13,19 +13,19 @@
#endif /* BASE_H */ #endif /* BASE_H */
struct nssListElementStr { struct nssListElementStr {
PRCList link; PRCList link;
void *data; void *data;
}; };
typedef struct nssListElementStr nssListElement; typedef struct nssListElementStr nssListElement;
struct nssListStr { struct nssListStr {
NSSArena *arena; NSSArena *arena;
PZLock *lock; PZLock *lock;
nssListElement *head; nssListElement *head;
PRUint32 count; PRUint32 count;
nssListCompareFunc compareFunc; nssListCompareFunc compareFunc;
nssListSortFunc sortFunc; nssListSortFunc sortFunc;
PRBool i_alloced_arena; PRBool i_alloced_arena;
}; };
@ -35,11 +35,13 @@ struct nssListIteratorStr {
nssListElement *current; nssListElement *current;
}; };
#define NSSLIST_LOCK_IF(list) \ #define NSSLIST_LOCK_IF(list) \
if ((list)->lock) PZ_Lock((list)->lock) if ((list)->lock) \
PZ_Lock((list)->lock)
#define NSSLIST_UNLOCK_IF(list) \ #define NSSLIST_UNLOCK_IF(list) \
if ((list)->lock) PZ_Unlock((list)->lock) if ((list)->lock) \
PZ_Unlock((list)->lock)
static PRBool static PRBool
pointer_compare(void *a, void *b) pointer_compare(void *a, void *b)
@ -54,61 +56,59 @@ nsslist_get_matching_element(nssList *list, void *data)
nssListElement *node; nssListElement *node;
node = list->head; node = list->head;
if (!node) { if (!node) {
return NULL; return NULL;
} }
link = &node->link; link = &node->link;
while (node) { while (node) {
/* using a callback slows things down when it's just compare ... */ /* using a callback slows things down when it's just compare ... */
if (list->compareFunc(node->data, data)) { if (list->compareFunc(node->data, data)) {
break; break;
} }
link = &node->link; link = &node->link;
if (link == PR_LIST_TAIL(&list->head->link)) { if (link == PR_LIST_TAIL(&list->head->link)) {
node = NULL; node = NULL;
break; break;
} }
node = (nssListElement *)PR_NEXT_LINK(&node->link); node = (nssListElement *)PR_NEXT_LINK(&node->link);
} }
return node; return node;
} }
NSS_IMPLEMENT nssList * NSS_IMPLEMENT nssList *
nssList_Create nssList_Create(NSSArena *arenaOpt, PRBool threadSafe)
(
NSSArena *arenaOpt,
PRBool threadSafe
)
{ {
NSSArena *arena; NSSArena *arena;
nssList *list; nssList *list;
PRBool i_alloced; PRBool i_alloced;
if (arenaOpt) { if (arenaOpt) {
arena = arenaOpt; arena = arenaOpt;
i_alloced = PR_FALSE; i_alloced = PR_FALSE;
} else { }
arena = nssArena_Create(); else {
i_alloced = PR_TRUE; arena = nssArena_Create();
i_alloced = PR_TRUE;
} }
if (!arena) { if (!arena) {
return (nssList *)NULL; return (nssList *)NULL;
} }
list = nss_ZNEW(arena, nssList); list = nss_ZNEW(arena, nssList);
if (!list) { if (!list) {
if (!arenaOpt) { if (!arenaOpt) {
NSSArena_Destroy(arena); NSSArena_Destroy(arena);
} }
return (nssList *)NULL; return (nssList *)NULL;
} }
if (threadSafe) { if (threadSafe) {
list->lock = PZ_NewLock(nssILockOther); list->lock = PZ_NewLock(nssILockOther);
if (!list->lock) { if (!list->lock) {
if (arenaOpt) { if (arenaOpt) {
nss_ZFreeIf(list); nss_ZFreeIf(list);
} else { }
NSSArena_Destroy(arena); else {
} NSSArena_Destroy(arena);
return (nssList *)NULL; }
} return (nssList *)NULL;
}
} }
list->arena = arena; list->arena = arena;
list->i_alloced_arena = i_alloced; list->i_alloced_arena = i_alloced;
@ -120,14 +120,14 @@ NSS_IMPLEMENT PRStatus
nssList_Destroy(nssList *list) nssList_Destroy(nssList *list)
{ {
if (!list->i_alloced_arena) { if (!list->i_alloced_arena) {
nssList_Clear(list, NULL); nssList_Clear(list, NULL);
} }
if (list->lock) { if (list->lock) {
(void)PZ_DestroyLock(list->lock); (void)PZ_DestroyLock(list->lock);
} }
if (list->i_alloced_arena) { if (list->i_alloced_arena) {
NSSArena_Destroy(list->arena); NSSArena_Destroy(list->arena);
list = NULL; list = NULL;
} }
nss_ZFreeIf(list); nss_ZFreeIf(list);
return PR_SUCCESS; return PR_SUCCESS;
@ -161,13 +161,14 @@ nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
node = list->head; node = list->head;
list->head = NULL; list->head = NULL;
while (node && list->count > 0) { while (node && list->count > 0) {
if (destructor) (*destructor)(node->data); if (destructor)
link = &node->link; (*destructor)(node->data);
tmp = (nssListElement *)PR_NEXT_LINK(link); link = &node->link;
PR_REMOVE_LINK(link); tmp = (nssListElement *)PR_NEXT_LINK(link);
nss_ZFreeIf(node); PR_REMOVE_LINK(link);
node = tmp; nss_ZFreeIf(node);
--list->count; node = tmp;
--list->count;
} }
NSSLIST_UNLOCK_IF(list); NSSLIST_UNLOCK_IF(list);
} }
@ -177,38 +178,41 @@ nsslist_add_element(nssList *list, void *data)
{ {
nssListElement *node = nss_ZNEW(list->arena, nssListElement); nssListElement *node = nss_ZNEW(list->arena, nssListElement);
if (!node) { if (!node) {
return PR_FAILURE; return PR_FAILURE;
} }
PR_INIT_CLIST(&node->link); PR_INIT_CLIST(&node->link);
node->data = data; node->data = data;
if (list->head) { if (list->head) {
if (list->sortFunc) { if (list->sortFunc) {
PRCList *link; PRCList *link;
nssListElement *currNode; nssListElement *currNode;
currNode = list->head; currNode = list->head;
/* insert in ordered list */ /* insert in ordered list */
while (currNode) { while (currNode) {
link = &currNode->link; link = &currNode->link;
if (list->sortFunc(data, currNode->data) <= 0) { if (list->sortFunc(data, currNode->data) <= 0) {
/* new element goes before current node */ /* new element goes before current node */
PR_INSERT_BEFORE(&node->link, link); PR_INSERT_BEFORE(&node->link, link);
/* reset head if this is first */ /* reset head if this is first */
if (currNode == list->head) list->head = node; if (currNode == list->head)
break; list->head = node;
} break;
if (link == PR_LIST_TAIL(&list->head->link)) { }
/* reached end of list, append */ if (link == PR_LIST_TAIL(&list->head->link)) {
PR_INSERT_AFTER(&node->link, link); /* reached end of list, append */
break; PR_INSERT_AFTER(&node->link, link);
} break;
currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link); }
} currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
} else { }
/* not sorting */ }
PR_APPEND_LINK(&node->link, &list->head->link); else {
} /* not sorting */
} else { PR_APPEND_LINK(&node->link, &list->head->link);
list->head = node; }
}
else {
list->head = node;
} }
++list->count; ++list->count;
return PR_SUCCESS; return PR_SUCCESS;
@ -231,9 +235,9 @@ nssList_AddUnique(nssList *list, void *data)
NSSLIST_LOCK_IF(list); NSSLIST_LOCK_IF(list);
node = nsslist_get_matching_element(list, data); node = nsslist_get_matching_element(list, data);
if (node) { if (node) {
/* already in, finish */ /* already in, finish */
NSSLIST_UNLOCK_IF(list); NSSLIST_UNLOCK_IF(list);
return PR_SUCCESS; return PR_SUCCESS;
} }
nssrv = nsslist_add_element(list, data); nssrv = nsslist_add_element(list, data);
NSSLIST_UNLOCK_IF(list); NSSLIST_UNLOCK_IF(list);
@ -247,14 +251,14 @@ nssList_Remove(nssList *list, void *data)
NSSLIST_LOCK_IF(list); NSSLIST_LOCK_IF(list);
node = nsslist_get_matching_element(list, data); node = nsslist_get_matching_element(list, data);
if (node) { if (node) {
if (node == list->head) { if (node == list->head) {
list->head = (nssListElement *)PR_NEXT_LINK(&node->link); list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
} }
PR_REMOVE_LINK(&node->link); PR_REMOVE_LINK(&node->link);
nss_ZFreeIf(node); nss_ZFreeIf(node);
if (--list->count == 0) { if (--list->count == 0) {
list->head = NULL; list->head = NULL;
} }
} }
NSSLIST_UNLOCK_IF(list); NSSLIST_UNLOCK_IF(list);
return PR_SUCCESS; return PR_SUCCESS;
@ -284,16 +288,17 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
PR_ASSERT(maxElements > 0); PR_ASSERT(maxElements > 0);
node = list->head; node = list->head;
if (!node) { if (!node) {
return PR_SUCCESS; return PR_SUCCESS;
} }
NSSLIST_LOCK_IF(list); NSSLIST_LOCK_IF(list);
while (node) { while (node) {
rvArray[i++] = node->data; rvArray[i++] = node->data;
if (i == maxElements) break; if (i == maxElements)
node = (nssListElement *)PR_NEXT_LINK(&node->link); break;
if (node == list->head) { node = (nssListElement *)PR_NEXT_LINK(&node->link);
break; if (node == list->head) {
} break;
}
} }
NSSLIST_UNLOCK_IF(list); NSSLIST_UNLOCK_IF(list);
return PR_SUCCESS; return PR_SUCCESS;
@ -306,18 +311,18 @@ nssList_Clone(nssList *list)
nssListElement *node; nssListElement *node;
rvList = nssList_Create(NULL, (list->lock != NULL)); rvList = nssList_Create(NULL, (list->lock != NULL));
if (!rvList) { if (!rvList) {
return NULL; return NULL;
} }
NSSLIST_LOCK_IF(list); NSSLIST_LOCK_IF(list);
if (list->count > 0) { if (list->count > 0) {
node = list->head; node = list->head;
while (PR_TRUE) { while (PR_TRUE) {
nssList_Add(rvList, node->data); nssList_Add(rvList, node->data);
node = (nssListElement *)PR_NEXT_LINK(&node->link); node = (nssListElement *)PR_NEXT_LINK(&node->link);
if (node == list->head) { if (node == list->head) {
break; break;
} }
} }
} }
NSSLIST_UNLOCK_IF(list); NSSLIST_UNLOCK_IF(list);
return rvList; return rvList;
@ -329,21 +334,21 @@ nssList_CreateIterator(nssList *list)
nssListIterator *rvIterator; nssListIterator *rvIterator;
rvIterator = nss_ZNEW(NULL, nssListIterator); rvIterator = nss_ZNEW(NULL, nssListIterator);
if (!rvIterator) { if (!rvIterator) {
return NULL; return NULL;
} }
rvIterator->list = nssList_Clone(list); rvIterator->list = nssList_Clone(list);
if (!rvIterator->list) { if (!rvIterator->list) {
nss_ZFreeIf(rvIterator); nss_ZFreeIf(rvIterator);
return NULL; return NULL;
} }
rvIterator->current = rvIterator->list->head; rvIterator->current = rvIterator->list->head;
if (list->lock) { if (list->lock) {
rvIterator->lock = PZ_NewLock(nssILockOther); rvIterator->lock = PZ_NewLock(nssILockOther);
if (!rvIterator->lock) { if (!rvIterator->lock) {
nssList_Destroy(rvIterator->list); nssList_Destroy(rvIterator->list);
nss_ZFreeIf(rvIterator); nss_ZFreeIf(rvIterator);
rvIterator = NULL; rvIterator = NULL;
} }
} }
return rvIterator; return rvIterator;
} }
@ -352,7 +357,7 @@ NSS_IMPLEMENT void
nssListIterator_Destroy(nssListIterator *iter) nssListIterator_Destroy(nssListIterator *iter)
{ {
if (iter->lock) { if (iter->lock) {
(void)PZ_DestroyLock(iter->lock); (void)PZ_DestroyLock(iter->lock);
} }
nssList_Destroy(iter->list); nssList_Destroy(iter->list);
nss_ZFreeIf(iter); nss_ZFreeIf(iter);
@ -363,7 +368,7 @@ nssListIterator_Start(nssListIterator *iter)
{ {
NSSLIST_LOCK_IF(iter); NSSLIST_LOCK_IF(iter);
if (iter->list->count == 0) { if (iter->list->count == 0) {
return NULL; return NULL;
} }
iter->current = iter->list->head; iter->current = iter->list->head;
return iter->current->data; return iter->current->data;
@ -375,17 +380,17 @@ nssListIterator_Next(nssListIterator *iter)
nssListElement *node; nssListElement *node;
PRCList *link; PRCList *link;
if (iter->list->count == 1 || iter->current == NULL) { if (iter->list->count == 1 || iter->current == NULL) {
/* Reached the end of the list. Don't change the state, force to /* Reached the end of the list. Don't change the state, force to
* user to call nssList_Finish to clean up. * user to call nssList_Finish to clean up.
*/ */
return NULL; return NULL;
} }
node = (nssListElement *)PR_NEXT_LINK(&iter->current->link); node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
link = &node->link; link = &node->link;
if (link == PR_LIST_TAIL(&iter->list->head->link)) { if (link == PR_LIST_TAIL(&iter->list->head->link)) {
/* Signal the end of the list. */ /* Signal the end of the list. */
iter->current = NULL; iter->current = NULL;
return node->data; return node->data;
} }
iter->current = node; iter->current = node;
return node->data; return node->data;
@ -397,4 +402,3 @@ nssListIterator_Finish(nssListIterator *iter)
iter->current = iter->list->head; iter->current = iter->list->head;
return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS; return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
} }

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

@ -44,11 +44,7 @@ PR_BEGIN_EXTERN_C
* A pointer to an NSSArena upon success * A pointer to an NSSArena upon success
*/ */
NSS_EXTERN NSSArena * NSS_EXTERN NSSArena *NSSArena_Create(void);
NSSArena_Create
(
void
);
extern const NSSError NSS_ERROR_NO_MEMORY; extern const NSSError NSS_ERROR_NO_MEMORY;
@ -56,7 +52,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* NSSArena_Destroy * NSSArena_Destroy
* *
* This routine will destroy the specified arena, freeing all memory * This routine will destroy the specified arena, freeing all memory
* allocated from it. This routine returns a PRStatus value; if * allocated from it. This routine returns a PRStatus value; if
* successful, it will return PR_SUCCESS. If unsuccessful, it will * successful, it will return PR_SUCCESS. If unsuccessful, it will
* create an error stack and return PR_FAILURE. * create an error stack and return PR_FAILURE.
* *
@ -68,11 +64,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* PR_FAILURE upon failure * PR_FAILURE upon failure
*/ */
NSS_EXTERN PRStatus NSS_EXTERN PRStatus NSSArena_Destroy(NSSArena *arena);
NSSArena_Destroy
(
NSSArena *arena
);
extern const NSSError NSS_ERROR_INVALID_ARENA; extern const NSSError NSS_ERROR_INVALID_ARENA;
@ -100,25 +92,21 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
* A nonzero error number * A nonzero error number
*/ */
NSS_EXTERN NSSError NSS_EXTERN NSSError NSS_GetError(void);
NSS_GetError
(
void
);
extern const NSSError NSS_ERROR_NO_ERROR; extern const NSSError NSS_ERROR_NO_ERROR;
/* /*
* NSS_GetErrorStack * NSS_GetErrorStack
* *
* This routine returns a pointer to an array of NSSError values, * This routine returns a pointer to an array of NSSError values,
* containingthe entire sequence or "stack" of errors set by the most * containingthe entire sequence or "stack" of errors set by the most
* recent NSS library routine called by the same thread calling this * recent NSS library routine called by the same thread calling this
* routine. NOTE: the caller DOES NOT OWN the memory pointed to by * routine. NOTE: the caller DOES NOT OWN the memory pointed to by
* the return value. The pointer will remain valid until the calling * the return value. The pointer will remain valid until the calling
* thread calls another NSS routine. The lowest-level (most specific) * thread calls another NSS routine. The lowest-level (most specific)
* error is first in the array, and the highest-level is last. The * error is first in the array, and the highest-level is last. The
* array is zero-terminated. This routine may return NULL upon error; * array is zero-terminated. This routine may return NULL upon error;
* this indicates a low-memory situation. * this indicates a low-memory situation.
* *
* Return value: * Return value:
@ -126,21 +114,17 @@ extern const NSSError NSS_ERROR_NO_ERROR;
* A NON-caller-owned pointer to an array of NSSError values * A NON-caller-owned pointer to an array of NSSError values
*/ */
NSS_EXTERN NSSError * NSS_EXTERN NSSError *NSS_GetErrorStack(void);
NSS_GetErrorStack
(
void
);
/* /*
* NSS_ZNEW * NSS_ZNEW
* *
* This preprocessor macro will allocate memory for a new object * This preprocessor macro will allocate memory for a new object
* of the specified type with nss_ZAlloc, and will cast the * of the specified type with nss_ZAlloc, and will cast the
* return value appropriately. If the optional arena argument is * return value appropriately. If the optional arena argument is
* non-null, the memory will be obtained from that arena; otherwise, * non-null, the memory will be obtained from that arena; otherwise,
* the memory will be obtained from the heap. This routine may * the memory will be obtained from the heap. This routine may
* return NULL upon error, in which case it will have set an error * return NULL upon error, in which case it will have set an error
* upon the error stack. * upon the error stack.
* *
* The error may be one of the following values: * The error may be one of the following values:
@ -152,7 +136,6 @@ NSS_GetErrorStack
* A pointer to the new segment of zeroed memory * A pointer to the new segment of zeroed memory
*/ */
/* The following line exceeds 72 characters, but emacs barfs if we split it. */
#define NSS_ZNEW(arenaOpt, type) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type))) #define NSS_ZNEW(arenaOpt, type) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type)))
/* /*
@ -160,10 +143,10 @@ NSS_GetErrorStack
* *
* This preprocessor macro will allocate memory for an array of * This preprocessor macro will allocate memory for an array of
* new objects, and will cast the return value appropriately. * new objects, and will cast the return value appropriately.
* If the optional arena argument is non-null, the memory will * If the optional arena argument is non-null, the memory will
* be obtained from that arena; otherwise, the memory will be * be obtained from that arena; otherwise, the memory will be
* obtained from the heap. This routine may return NULL upon * obtained from the heap. This routine may return NULL upon
* error, in which case it will have set an error upon the error * error, in which case it will have set an error upon the error
* stack. The array size may be specified as zero. * stack. The array size may be specified as zero.
* *
* The error may be one of the following values: * The error may be one of the following values:
@ -175,20 +158,19 @@ NSS_GetErrorStack
* A pointer to the new segment of zeroed memory * A pointer to the new segment of zeroed memory
*/ */
/* The following line exceeds 72 characters, but emacs barfs if we split it. */ #define NSS_ZNEWARRAY(arenaOpt, type, quantity) \
#define NSS_ZNEWARRAY(arenaOpt, type, quantity) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity))) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
/* /*
* NSS_ZAlloc * NSS_ZAlloc
* *
* This routine allocates and zeroes a section of memory of the * This routine allocates and zeroes a section of memory of the
* size, and returns to the caller a pointer to that memory. If * size, and returns to the caller a pointer to that memory. If
* the optional arena argument is non-null, the memory will be * the optional arena argument is non-null, the memory will be
* obtained from that arena; otherwise, the memory will be obtained * obtained from that arena; otherwise, the memory will be obtained
* from the heap. This routine may return NULL upon error, in * from the heap. This routine may return NULL upon error, in
* which case it will have set an error upon the error stack. The * which case it will have set an error upon the error stack. The
* value specified for size may be zero; in which case a valid * value specified for size may be zero; in which case a valid
* zero-length block of memory will be allocated. This block may * zero-length block of memory will be allocated. This block may
* be expanded by calling NSS_ZRealloc. * be expanded by calling NSS_ZRealloc.
* *
@ -202,21 +184,16 @@ NSS_GetErrorStack
* A pointer to the new segment of zeroed memory * A pointer to the new segment of zeroed memory
*/ */
NSS_EXTERN void * NSS_EXTERN void *NSS_ZAlloc(NSSArena *arenaOpt, PRUint32 size);
NSS_ZAlloc
(
NSSArena *arenaOpt,
PRUint32 size
);
/* /*
* NSS_ZRealloc * NSS_ZRealloc
* *
* This routine reallocates a block of memory obtained by calling * This routine reallocates a block of memory obtained by calling
* nss_ZAlloc or nss_ZRealloc. The portion of memory * nss_ZAlloc or nss_ZRealloc. The portion of memory
* between the new and old sizes -- which is either being newly * between the new and old sizes -- which is either being newly
* obtained or released -- is in either case zeroed. This routine * obtained or released -- is in either case zeroed. This routine
* may return NULL upon failure, in which case it will have placed * may return NULL upon failure, in which case it will have placed
* an error on the error stack. * an error on the error stack.
* *
* The error may be one of the following values: * The error may be one of the following values:
@ -229,13 +206,7 @@ NSS_ZAlloc
* A pointer to the replacement segment of memory * A pointer to the replacement segment of memory
*/ */
NSS_EXTERN void * NSS_EXTERN void *NSS_ZRealloc(void *pointer, PRUint32 newSize);
NSS_ZRealloc
(
void *pointer,
PRUint32 newSize
);
/* /*
* NSS_ZFreeIf * NSS_ZFreeIf
@ -255,11 +226,7 @@ NSS_ZRealloc
* PR_FAILURE * PR_FAILURE
*/ */
NSS_EXTERN PRStatus NSS_EXTERN PRStatus NSS_ZFreeIf(void *pointer);
NSS_ZFreeIf
(
void *pointer
);
PR_END_EXTERN_C PR_END_EXTERN_C

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

@ -18,16 +18,16 @@
* NSS_EXTERN, NSS_IMPLEMENT, NSS_EXTERN_DATA, NSS_IMPLEMENT_DATA * NSS_EXTERN, NSS_IMPLEMENT, NSS_EXTERN_DATA, NSS_IMPLEMENT_DATA
* *
* NSS has its own versions of these NSPR macros, in a form which * NSS has its own versions of these NSPR macros, in a form which
* does not confuse ctags and other related utilities. NSPR * does not confuse ctags and other related utilities. NSPR
* defines these macros to take the type as an argument, because * defines these macros to take the type as an argument, because
* of certain OS requirements on platforms not supported by NSS. * of certain OS requirements on platforms not supported by NSS.
*/ */
#define DUMMY /* dummy */ #define DUMMY /* dummy */
#define NSS_EXTERN extern #define NSS_EXTERN extern
#define NSS_EXTERN_DATA extern #define NSS_EXTERN_DATA extern
#define NSS_IMPLEMENT #define NSS_IMPLEMENT
#define NSS_IMPLEMENT_DATA #define NSS_IMPLEMENT_DATA
PR_BEGIN_EXTERN_C PR_BEGIN_EXTERN_C
@ -36,7 +36,7 @@ PR_BEGIN_EXTERN_C
* *
* Calls to NSS routines may result in one or more errors being placed * Calls to NSS routines may result in one or more errors being placed
* on the calling thread's "error stack." Every possible error that * on the calling thread's "error stack." Every possible error that
* may be returned from a function is declared where the function is * may be returned from a function is declared where the function is
* prototyped. All errors are of the following type. * prototyped. All errors are of the following type.
*/ */
@ -47,7 +47,7 @@ typedef PRInt32 NSSError;
* *
* Arenas are logical sets of heap memory, from which memory may be * Arenas are logical sets of heap memory, from which memory may be
* allocated. When an arena is destroyed, all memory allocated within * allocated. When an arena is destroyed, all memory allocated within
* that arena is implicitly freed. These arenas are thread-safe: * that arena is implicitly freed. These arenas are thread-safe:
* an arena pointer may be used by multiple threads simultaneously. * an arena pointer may be used by multiple threads simultaneously.
* However, as they are not backed by shared memory, they may only be * However, as they are not backed by shared memory, they may only be
* used within one process. * used within one process.
@ -64,12 +64,11 @@ typedef struct NSSArenaStr NSSArena;
*/ */
struct NSSItemStr { struct NSSItemStr {
void *data; void *data;
PRUint32 size; PRUint32 size;
}; };
typedef struct NSSItemStr NSSItem; typedef struct NSSItemStr NSSItem;
/* /*
* NSSBER * NSSBER
* *

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

@ -4,7 +4,7 @@
/* /*
* tracker.c * tracker.c
* *
* This file contains the code used by the pointer-tracking calls used * This file contains the code used by the pointer-tracking calls used
* in the debug builds to catch bad pointers. The entire contents are * in the debug builds to catch bad pointers. The entire contents are
* only available in debug builds (both internal and external builds). * only available in debug builds (both internal and external builds).
@ -24,12 +24,9 @@
*/ */
static PLHashNumber PR_CALLBACK static PLHashNumber PR_CALLBACK
identity_hash identity_hash(const void *key)
(
const void *key
)
{ {
return (PLHashNumber)((char *)key - (char *)NULL); return (PLHashNumber)((char *)key - (char *)NULL);
} }
/* /*
@ -41,44 +38,38 @@ identity_hash
*/ */
static PRStatus static PRStatus
trackerOnceFunc trackerOnceFunc(void *arg)
(
void *arg
)
{ {
nssPointerTracker *tracker = (nssPointerTracker *)arg; nssPointerTracker *tracker = (nssPointerTracker *)arg;
tracker->lock = PZ_NewLock(nssILockOther); tracker->lock = PZ_NewLock(nssILockOther);
if( (PZLock *)NULL == tracker->lock ) { if ((PZLock *)NULL == tracker->lock) {
return PR_FAILURE; return PR_FAILURE;
} }
tracker->table = PL_NewHashTable(0, tracker->table =
identity_hash, PL_NewHashTable(0, identity_hash, PL_CompareValues, PL_CompareValues,
PL_CompareValues, (PLHashAllocOps *)NULL, (void *)NULL);
PL_CompareValues, if ((PLHashTable *)NULL == tracker->table) {
(PLHashAllocOps *)NULL, PZ_DestroyLock(tracker->lock);
(void *)NULL); tracker->lock = (PZLock *)NULL;
if( (PLHashTable *)NULL == tracker->table ) { return PR_FAILURE;
PZ_DestroyLock(tracker->lock); }
tracker->lock = (PZLock *)NULL;
return PR_FAILURE;
}
return PR_SUCCESS; return PR_SUCCESS;
} }
/* /*
* nssPointerTracker_initialize * nssPointerTracker_initialize
* *
* This method is only present in debug builds. * This method is only present in debug builds.
* *
* This routine initializes an nssPointerTracker object. Note that * This routine initializes an nssPointerTracker object. Note that
* the object must have been declared *static* to guarantee that it * the object must have been declared *static* to guarantee that it
* is in a zeroed state initially. This routine is idempotent, and * is in a zeroed state initially. This routine is idempotent, and
* may even be safely called by multiple threads simultaneously with * may even be safely called by multiple threads simultaneously with
* the same argument. This routine returns a PRStatus value; if * the same argument. This routine returns a PRStatus value; if
* successful, it will return PR_SUCCESS. On failure it will set an * successful, it will return PR_SUCCESS. On failure it will set an
* error on the error stack and return PR_FAILURE. * error on the error stack and return PR_FAILURE.
* *
* The error may be one of the following values: * The error may be one of the following values:
@ -90,17 +81,14 @@ trackerOnceFunc
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssPointerTracker_initialize nssPointerTracker_initialize(nssPointerTracker *tracker)
(
nssPointerTracker *tracker
)
{ {
PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker); PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
if( PR_SUCCESS != rv ) { if (PR_SUCCESS != rv) {
nss_SetError(NSS_ERROR_NO_MEMORY); nss_SetError(NSS_ERROR_NO_MEMORY);
} }
return rv; return rv;
} }
#ifdef DONT_DESTROY_EMPTY_TABLES #ifdef DONT_DESTROY_EMPTY_TABLES
@ -114,14 +102,9 @@ nssPointerTracker_initialize
*/ */
static PRIntn PR_CALLBACK static PRIntn PR_CALLBACK
count_entries count_entries(PLHashEntry *he, PRIntn index, void *arg)
(
PLHashEntry *he,
PRIntn index,
void *arg
)
{ {
return HT_ENUMERATE_NEXT; return HT_ENUMERATE_NEXT;
} }
#endif /* DONT_DESTROY_EMPTY_TABLES */ #endif /* DONT_DESTROY_EMPTY_TABLES */
@ -138,7 +121,7 @@ static const PRCallOnceType zero_once;
* nssPointerTracker_finalize * nssPointerTracker_finalize
* *
* This method is only present in debug builds. * This method is only present in debug builds.
* *
* This routine returns the nssPointerTracker object to the pre- * This routine returns the nssPointerTracker object to the pre-
* initialized state, releasing all resources used by the object. * initialized state, releasing all resources used by the object.
* It will *NOT* destroy the objects being tracked by the pointer * It will *NOT* destroy the objects being tracked by the pointer
@ -160,58 +143,54 @@ static const PRCallOnceType zero_once;
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssPointerTracker_finalize nssPointerTracker_finalize(nssPointerTracker *tracker)
(
nssPointerTracker *tracker
)
{ {
PZLock *lock; PZLock *lock;
if( (nssPointerTracker *)NULL == tracker ) { if ((nssPointerTracker *)NULL == tracker) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return PR_FAILURE; return PR_FAILURE;
} }
if( (PZLock *)NULL == tracker->lock ) { if ((PZLock *)NULL == tracker->lock) {
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED); nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE; return PR_FAILURE;
} }
lock = tracker->lock; lock = tracker->lock;
PZ_Lock(lock); PZ_Lock(lock);
if( (PLHashTable *)NULL == tracker->table ) { if ((PLHashTable *)NULL == tracker->table) {
PZ_Unlock(lock); PZ_Unlock(lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED); nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE; return PR_FAILURE;
} }
#ifdef DONT_DESTROY_EMPTY_TABLES #ifdef DONT_DESTROY_EMPTY_TABLES
/* /*
* I changed my mind; I think we don't want this after all. * I changed my mind; I think we don't want this after all.
* Comments? * Comments?
*/ */
count = PL_HashTableEnumerateEntries(tracker->table, count = PL_HashTableEnumerateEntries(tracker->table, count_entries,
count_entries, (void *)NULL);
(void *)NULL);
if( 0 != count ) { if (0 != count) {
PZ_Unlock(lock); PZ_Unlock(lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY); nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
return PR_FAILURE; return PR_FAILURE;
} }
#endif /* DONT_DESTROY_EMPTY_TABLES */ #endif /* DONT_DESTROY_EMPTY_TABLES */
PL_HashTableDestroy(tracker->table); PL_HashTableDestroy(tracker->table);
/* memset(tracker, 0, sizeof(nssPointerTracker)); */ /* memset(tracker, 0, sizeof(nssPointerTracker)); */
tracker->once = zero_once; tracker->once = zero_once;
tracker->lock = (PZLock *)NULL; tracker->lock = (PZLock *)NULL;
tracker->table = (PLHashTable *)NULL; tracker->table = (PLHashTable *)NULL;
PZ_Unlock(lock); PZ_Unlock(lock);
PZ_DestroyLock(lock); PZ_DestroyLock(lock);
return PR_SUCCESS; return PR_SUCCESS;
} }
/* /*
@ -238,63 +217,59 @@ nssPointerTracker_finalize
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssPointerTracker_add nssPointerTracker_add(nssPointerTracker *tracker, const void *pointer)
(
nssPointerTracker *tracker,
const void *pointer
)
{ {
void *check; void *check;
PLHashEntry *entry; PLHashEntry *entry;
if( (nssPointerTracker *)NULL == tracker ) { if ((nssPointerTracker *)NULL == tracker) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return PR_FAILURE; return PR_FAILURE;
} }
if( (PZLock *)NULL == tracker->lock ) { if ((PZLock *)NULL == tracker->lock) {
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED); nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE; return PR_FAILURE;
} }
PZ_Lock(tracker->lock); PZ_Lock(tracker->lock);
if ((PLHashTable *)NULL == tracker->table) {
PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE;
}
check = PL_HashTableLookup(tracker->table, pointer);
if ((void *)NULL != check) {
PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_DUPLICATE_POINTER);
return PR_FAILURE;
}
entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
if( (PLHashTable *)NULL == tracker->table ) {
PZ_Unlock(tracker->lock); PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE;
}
check = PL_HashTableLookup(tracker->table, pointer); if ((PLHashEntry *)NULL == entry) {
if( (void *)NULL != check ) { nss_SetError(NSS_ERROR_NO_MEMORY);
PZ_Unlock(tracker->lock); return PR_FAILURE;
nss_SetError(NSS_ERROR_DUPLICATE_POINTER); }
return PR_FAILURE;
}
entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer); return PR_SUCCESS;
PZ_Unlock(tracker->lock);
if( (PLHashEntry *)NULL == entry ) {
nss_SetError(NSS_ERROR_NO_MEMORY);
return PR_FAILURE;
}
return PR_SUCCESS;
} }
/* /*
* nssPointerTracker_remove * nssPointerTracker_remove
* *
* This method is only present in debug builds. * This method is only present in debug builds.
* *
* This routine removes the specified pointer from the * This routine removes the specified pointer from the
* nssPointerTracker object. It does not call any destructor for the * nssPointerTracker object. It does not call any destructor for the
* object; rather, this should be called from the object's destructor. * object; rather, this should be called from the object's destructor.
* The nssPointerTracker is threadsafe, but this call is not * The nssPointerTracker is threadsafe, but this call is not
* idempotent. This routine returns a PRStatus value; if successful * idempotent. This routine returns a PRStatus value; if successful
* it will return PR_SUCCESS. On failure it will set an error on the * it will return PR_SUCCESS. On failure it will set an error on the
* error stack and return PR_FAILURE. * error stack and return PR_FAILURE.
* *
* The error may be one of the following values: * The error may be one of the following values:
@ -308,41 +283,37 @@ nssPointerTracker_add
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssPointerTracker_remove nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer)
(
nssPointerTracker *tracker,
const void *pointer
)
{ {
PRBool registered; PRBool registered;
if( (nssPointerTracker *)NULL == tracker ) { if ((nssPointerTracker *)NULL == tracker) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return PR_FAILURE; return PR_FAILURE;
} }
if( (PZLock *)NULL == tracker->lock ) { if ((PZLock *)NULL == tracker->lock) {
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED); nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE; return PR_FAILURE;
} }
PZ_Lock(tracker->lock); PZ_Lock(tracker->lock);
if( (PLHashTable *)NULL == tracker->table ) { if ((PLHashTable *)NULL == tracker->table) {
PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE;
}
registered = PL_HashTableRemove(tracker->table, pointer);
PZ_Unlock(tracker->lock); PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE;
}
registered = PL_HashTableRemove(tracker->table, pointer); if (!registered) {
PZ_Unlock(tracker->lock); nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
return PR_FAILURE;
}
if( !registered ) { return PR_SUCCESS;
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
return PR_FAILURE;
}
return PR_SUCCESS;
} }
/* /*
@ -354,10 +325,10 @@ nssPointerTracker_remove
* with the nssPointerTracker object. The nssPointerTracker object is * with the nssPointerTracker object. The nssPointerTracker object is
* threadsafe, and this call may be safely called from multiple threads * threadsafe, and this call may be safely called from multiple threads
* simultaneously with the same arguments. This routine returns a * simultaneously with the same arguments. This routine returns a
* PRStatus value; if the pointer is registered this will return * PRStatus value; if the pointer is registered this will return
* PR_SUCCESS. Otherwise it will set an error on the error stack and * PR_SUCCESS. Otherwise it will set an error on the error stack and
* return PR_FAILURE. Although the error is suitable for leaving on * return PR_FAILURE. Although the error is suitable for leaving on
* the stack, callers may wish to augment the information available by * the stack, callers may wish to augment the information available by
* placing a more type-specific error on the stack. * placing a more type-specific error on the stack.
* *
* The error may be one of the following values: * The error may be one of the following values:
@ -371,41 +342,37 @@ nssPointerTracker_remove
*/ */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssPointerTracker_verify nssPointerTracker_verify(nssPointerTracker *tracker, const void *pointer)
(
nssPointerTracker *tracker,
const void *pointer
)
{ {
void *check; void *check;
if( (nssPointerTracker *)NULL == tracker ) { if ((nssPointerTracker *)NULL == tracker) {
nss_SetError(NSS_ERROR_INVALID_POINTER); nss_SetError(NSS_ERROR_INVALID_POINTER);
return PR_FAILURE; return PR_FAILURE;
} }
if( (PZLock *)NULL == tracker->lock ) { if ((PZLock *)NULL == tracker->lock) {
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED); nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE; return PR_FAILURE;
} }
PZ_Lock(tracker->lock); PZ_Lock(tracker->lock);
if( (PLHashTable *)NULL == tracker->table ) { if ((PLHashTable *)NULL == tracker->table) {
PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE;
}
check = PL_HashTableLookup(tracker->table, pointer);
PZ_Unlock(tracker->lock); PZ_Unlock(tracker->lock);
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
return PR_FAILURE;
}
check = PL_HashTableLookup(tracker->table, pointer); if ((void *)NULL == check) {
PZ_Unlock(tracker->lock); nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
return PR_FAILURE;
}
if( (void *)NULL == check ) { return PR_SUCCESS;
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
return PR_FAILURE;
}
return PR_SUCCESS;
} }
#endif /* DEBUG */ #endif /* DEBUG */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -5,18 +5,17 @@
#ifndef _CERTDB_H_ #ifndef _CERTDB_H_
#define _CERTDB_H_ #define _CERTDB_H_
/* common flags for all types of certificates */ /* common flags for all types of certificates */
#define CERTDB_TERMINAL_RECORD (1u<<0) #define CERTDB_TERMINAL_RECORD (1u << 0)
#define CERTDB_TRUSTED (1u<<1) #define CERTDB_TRUSTED (1u << 1)
#define CERTDB_SEND_WARN (1u<<2) #define CERTDB_SEND_WARN (1u << 2)
#define CERTDB_VALID_CA (1u<<3) #define CERTDB_VALID_CA (1u << 3)
#define CERTDB_TRUSTED_CA (1u<<4) /* trusted for issuing server certs */ #define CERTDB_TRUSTED_CA (1u << 4) /* trusted for issuing server certs */
#define CERTDB_NS_TRUSTED_CA (1u<<5) #define CERTDB_NS_TRUSTED_CA (1u << 5)
#define CERTDB_USER (1u<<6) #define CERTDB_USER (1u << 6)
#define CERTDB_TRUSTED_CLIENT_CA (1u<<7) /* trusted for issuing client certs */ #define CERTDB_TRUSTED_CLIENT_CA (1u << 7) /* trusted for issuing client certs */
#define CERTDB_INVISIBLE_CA (1u<<8) /* don't show in UI */ #define CERTDB_INVISIBLE_CA (1u << 8) /* don't show in UI */
#define CERTDB_GOVT_APPROVED_CA (1u<<9) /* can do strong crypto in export ver */ #define CERTDB_GOVT_APPROVED_CA (1u << 9) /* can do strong crypto in export ver */
/* old usage, to keep old programs compiling */ /* old usage, to keep old programs compiling */
/* On Windows, Mac, and Linux (and other gcc platforms), we can give compile /* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
@ -26,54 +25,48 @@
#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) #if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated)); typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
#else #else
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated typedef unsigned int __CERTDB_VALID_PEER __attribute__((
("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD"))); deprecated("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD")));
#endif #endif
#define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER) CERTDB_TERMINAL_RECORD) #define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER)CERTDB_TERMINAL_RECORD)
#else #else
#ifdef _WIN32 #ifdef _WIN32
#pragma deprecated(CERTDB_VALID_PEER) #pragma deprecated(CERTDB_VALID_PEER)
#endif #endif
#define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD #define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
#endif #endif
SEC_BEGIN_PROTOS SEC_BEGIN_PROTOS
CERTSignedCrl * CERTSignedCrl *SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey,
SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type); int type);
CERTSignedCrl * CERTSignedCrl *SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey,
SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type); int type);
CERTSignedCrl * CERTSignedCrl *SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl,
SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type); int type);
PRBool PRBool SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject, CERTCertDBHandle *handle);
CERTCertDBHandle *handle); CERTSignedCrl *SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl,
CERTSignedCrl * int type);
SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
SECStatus SECStatus SEC_DeletePermCRL(CERTSignedCrl *crl);
SEC_DeletePermCRL(CERTSignedCrl *crl);
SECStatus SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes,
int type);
SECStatus SECStatus SEC_DestroyCrl(CERTSignedCrl *crl);
SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type);
SECStatus CERTSignedCrl *SEC_DupCrl(CERTSignedCrl *acrl);
SEC_DestroyCrl(CERTSignedCrl *crl);
CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl); SECStatus CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
CERTCertTrust *trust);
SECStatus
CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
CERTCertTrust *trust);
SECStatus SEC_DeletePermCertificate(CERTCertificate *cert); SECStatus SEC_DeletePermCertificate(CERTCertificate *cert);
PRBool PRBool SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
/* /*
** Extract the validity times from a CRL ** Extract the validity times from a CRL
@ -81,8 +74,7 @@ SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
** "notBefore" is the start of the validity period (last update) ** "notBefore" is the start of the validity period (last update)
** "notAfter" is the end of the validity period (next update) ** "notAfter" is the end of the validity period (next update)
*/ */
SECStatus SECStatus SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
/* /*
** Check the validity times of a crl vs. time 't', allowing ** Check the validity times of a crl vs. time 't', allowing
@ -90,8 +82,7 @@ SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
** "crl" is the certificate to be checked ** "crl" is the certificate to be checked
** "t" is the time to check against ** "t" is the time to check against
*/ */
SECCertTimeValidity SECCertTimeValidity SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
SEC_END_PROTOS SEC_END_PROTOS

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

@ -38,8 +38,7 @@ struct OpaqueCRLFieldsStr {
typedef struct PreAllocatorStr PreAllocator; typedef struct PreAllocatorStr PreAllocator;
struct PreAllocatorStr struct PreAllocatorStr {
{
PRSize len; PRSize len;
void* data; void* data;
PRSize used; PRSize used;
@ -56,32 +55,31 @@ struct CRLEntryCacheStr {
CRLEntryCache *prev, *next; CRLEntryCache *prev, *next;
}; };
#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set #define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
if we have CRL objects with an invalid DER or signature. Can be if we have CRL objects with an invalid DER or signature. Can be
cleared if the invalid objects are deleted from the token */ cleared if the invalid objects are deleted from the token */
#define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set #define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set
if the last CRL fetch encountered an error. Can be cleared if a if the last CRL fetch encountered an error. Can be cleared if a
new fetch succeeds */ new fetch succeeds */
#define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set #define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set
if we don't have enough memory to build the hash table of entries */ if we don't have enough memory to build the hash table of entries */
typedef enum { typedef enum {
CRL_OriginToken = 0, /* CRL came from PKCS#11 token */ CRL_OriginToken = 0, /* CRL came from PKCS#11 token */
CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */ CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */
} CRLOrigin; } CRLOrigin;
typedef enum { typedef enum {
dpcacheNoEntry = 0, /* no entry found for this SN */ dpcacheNoEntry = 0, /* no entry found for this SN */
dpcacheFoundEntry = 1, /* entry found for this SN */ dpcacheFoundEntry = 1, /* entry found for this SN */
dpcacheCallerError = 2, /* invalid args */ dpcacheCallerError = 2, /* invalid args */
dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */ dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */
/* or unverified */ /* or unverified */
dpcacheEmpty = 4, /* no CRL in cache */ dpcacheEmpty = 4, /* no CRL in cache */
dpcacheLookupError = 5 /* internal error */ dpcacheLookupError = 5 /* internal error */
} dpcacheStatus; } dpcacheStatus;
struct CachedCrlStr { struct CachedCrlStr {
CERTSignedCrl* crl; CERTSignedCrl* crl;
CRLOrigin origin; CRLOrigin origin;
@ -98,11 +96,11 @@ struct CachedCrlStr {
*/ */
PLHashTable* entries; PLHashTable* entries;
PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */ PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */
PRBool sigChecked; /* this CRL signature has already been checked */ PRBool sigChecked; /* this CRL signature has already been checked */
PRBool sigValid; /* signature verification status . PRBool sigValid; /* signature verification status .
Only meaningful if checked is PR_TRUE . */ Only meaningful if checked is PR_TRUE . */
PRBool unbuildable; /* Avoid using assosiated CRL is it fails PRBool unbuildable; /* Avoid using assosiated CRL is it fails
* a decoding step */ * a decoding step */
}; };
/* CRL distribution point cache object /* CRL distribution point cache object
@ -116,15 +114,15 @@ struct CRLDPCacheStr {
#else #else
PRLock* lock; PRLock* lock;
#endif #endif
SECItem *issuerDERCert; /* issuer DER cert. Don't hold a reference SECItem* issuerDERCert; /* issuer DER cert. Don't hold a reference
to the actual cert so the trust can be to the actual cert so the trust can be
updated on the cert automatically. updated on the cert automatically.
XXX there may be multiple issuer certs, XXX there may be multiple issuer certs,
with different validity dates. Also with different validity dates. Also
need to deal with SKID/AKID . See need to deal with SKID/AKID . See
bugzilla 217387, 233118 */ bugzilla 217387, 233118 */
CERTCertDBHandle *dbHandle; CERTCertDBHandle* dbHandle;
SECItem* subject; /* DER of issuer subject */ SECItem* subject; /* DER of issuer subject */
SECItem* distributionPoint; /* DER of distribution point. This may be SECItem* distributionPoint; /* DER of distribution point. This may be
@ -133,31 +131,31 @@ struct CRLDPCacheStr {
Currently not used. */ Currently not used. */
/* array of full CRLs matching this distribution point */ /* array of full CRLs matching this distribution point */
PRUint32 ncrls; /* total number of CRLs in crls */ PRUint32 ncrls; /* total number of CRLs in crls */
CachedCrl** crls; /* array of all matching CRLs */ CachedCrl** crls; /* array of all matching CRLs */
/* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several /* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several
issuers. In the future, we'll need to globally recycle the CRL in a issuers. In the future, we'll need to globally recycle the CRL in a
separate list in order to avoid extra lookups, decodes, and copies */ separate list in order to avoid extra lookups, decodes, and copies */
/* pointers to good decoded CRLs used to build the cache */ /* pointers to good decoded CRLs used to build the cache */
CachedCrl* selected; /* full CRL selected for use in the cache */ CachedCrl* selected; /* full CRL selected for use in the cache */
#if 0 #if 0
/* for future use */ /* for future use */
PRInt32 numdeltas; /* number of delta CRLs used for the cache */ PRInt32 numdeltas; /* number of delta CRLs used for the cache */
CachedCrl** deltas; /* delta CRLs used for the cache */ CachedCrl** deltas; /* delta CRLs used for the cache */
#endif #endif
/* cache invalidity bitflag */ /* cache invalidity bitflag */
PRUint16 invalid; /* this state will be set if either PRUint16 invalid; /* this state will be set if either
CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set. CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
In those cases, all certs are considered to have unknown status. In those cases, all certs are considered to have unknown status.
The invalid state can only be cleared during an update if all The invalid state can only be cleared during an update if all
error states are cleared */ error states are cleared */
PRBool refresh; /* manual refresh from tokens has been forced */ PRBool refresh; /* manual refresh from tokens has been forced */
PRBool mustchoose; /* trigger reselection algorithm, for case when PRBool mustchoose; /* trigger reselection algorithm, for case when
RAM CRL objects are dropped from the cache */ RAM CRL objects are dropped from the cache */
PRTime lastfetch; /* time a CRL token fetch was last performed */ PRTime lastfetch; /* time a CRL token fetch was last performed */
PRTime lastcheck; /* time CRL token objects were last checked for PRTime lastcheck; /* time CRL token objects were last checked for
existence */ existence */
}; };
/* CRL issuer cache object /* CRL issuer cache object
@ -168,7 +166,7 @@ struct CRLDPCacheStr {
*/ */
struct CRLIssuerCacheStr { struct CRLIssuerCacheStr {
SECItem* subject; /* DER of issuer subject */ SECItem* subject; /* DER of issuer subject */
CRLDPCache* dpp; CRLDPCache* dpp;
}; };
@ -194,46 +192,40 @@ SECStatus ShutdownCRLCache(void);
** null-terminated strings, terminated by a zero-length string. ** null-terminated strings, terminated by a zero-length string.
** This function is intended to be internal to NSS. ** This function is intended to be internal to NSS.
*/ */
extern char * cert_GetCertificateEmailAddresses(CERTCertificate *cert); extern char* cert_GetCertificateEmailAddresses(CERTCertificate* cert);
/* /*
* These functions are used to map subjectKeyID extension values to certs * These functions are used to map subjectKeyID extension values to certs
* and to keep track of the checks for user certificates in each slot * and to keep track of the checks for user certificates in each slot
*/ */
SECStatus SECStatus cert_CreateSubjectKeyIDHashTable(void);
cert_CreateSubjectKeyIDHashTable(void);
SECStatus SECStatus cert_AddSubjectKeyIDMapping(SECItem* subjKeyID,
cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert); CERTCertificate* cert);
SECStatus SECStatus cert_UpdateSubjectKeyIDSlotCheck(SECItem* slotid, int series);
cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series);
int int cert_SubjectKeyIDSlotCheckSeries(SECItem* slotid);
cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid);
/* /*
* Call this function to remove an entry from the mapping table. * Call this function to remove an entry from the mapping table.
*/ */
SECStatus SECStatus cert_RemoveSubjectKeyIDMapping(SECItem* subjKeyID);
cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID);
SECStatus SECStatus cert_DestroySubjectKeyIDHashTable(void);
cert_DestroySubjectKeyIDHashTable(void);
SECItem* SECItem* cert_FindDERCertBySubjectKeyID(SECItem* subjKeyID);
cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID);
/* return maximum length of AVA value based on its type OID tag. */ /* return maximum length of AVA value based on its type OID tag. */
extern int cert_AVAOidTagToMaxLen(SECOidTag tag); extern int cert_AVAOidTagToMaxLen(SECOidTag tag);
/* Make an AVA, allocated from pool, from OID and DER encoded value */ /* Make an AVA, allocated from pool, from OID and DER encoded value */
extern CERTAVA * CERT_CreateAVAFromRaw(PLArenaPool *pool, extern CERTAVA* CERT_CreateAVAFromRaw(PLArenaPool* pool, const SECItem* OID,
const SECItem * OID, const SECItem * value); const SECItem* value);
/* Make an AVA from binary input specified by SECItem */ /* Make an AVA from binary input specified by SECItem */
extern CERTAVA * CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, extern CERTAVA* CERT_CreateAVAFromSECItem(PLArenaPool* arena, SECOidTag kind,
int valueType, SECItem *value); int valueType, SECItem* value);
/* /*
* get a DPCache object for the given issuer subject and dp * get a DPCache object for the given issuer subject and dp
@ -260,10 +252,11 @@ void CERT_MapStanError();
/* Like CERT_VerifyCert, except with an additional argument, flags. The /* Like CERT_VerifyCert, except with an additional argument, flags. The
* flags are defined immediately below. * flags are defined immediately below.
*/ */
SECStatus SECStatus cert_VerifyCertWithFlags(CERTCertDBHandle* handle,
cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert, CERTCertificate* cert, PRBool checkSig,
PRBool checkSig, SECCertUsage certUsage, PRTime t, SECCertUsage certUsage, PRTime t,
PRUint32 flags, void *wincx, CERTVerifyLog *log); PRUint32 flags, void* wincx,
CERTVerifyLog* log);
/* Use the default settings. /* Use the default settings.
* cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is * cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is
@ -281,15 +274,10 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
/* Interface function for libpkix cert validation engine: /* Interface function for libpkix cert validation engine:
* cert_verify wrapper. */ * cert_verify wrapper. */
SECStatus SECStatus cert_VerifyCertChainPkix(CERTCertificate* cert, PRBool checkSig,
cert_VerifyCertChainPkix(CERTCertificate *cert, SECCertUsage requiredUsage, PRTime time,
PRBool checkSig, void* wincx, CERTVerifyLog* log,
SECCertUsage requiredUsage, PRBool* sigError, PRBool* revoked);
PRTime time,
void *wincx,
CERTVerifyLog *log,
PRBool *sigError,
PRBool *revoked);
SECStatus cert_InitLocks(void); SECStatus cert_InitLocks(void);
@ -298,17 +286,16 @@ SECStatus cert_DestroyLocks(void);
/* /*
* fill in nsCertType field of the cert based on the cert extension * fill in nsCertType field of the cert based on the cert extension
*/ */
extern SECStatus cert_GetCertType(CERTCertificate *cert); extern SECStatus cert_GetCertType(CERTCertificate* cert);
/* /*
* compute and return the value of nsCertType for cert, but do not * compute and return the value of nsCertType for cert, but do not
* update the CERTCertificate. * update the CERTCertificate.
*/ */
extern PRUint32 cert_ComputeCertType(CERTCertificate *cert); extern PRUint32 cert_ComputeCertType(CERTCertificate* cert);
void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert, void cert_AddToVerifyLog(CERTVerifyLog* log, CERTCertificate* cert,
long errorCode, unsigned int depth, long errorCode, unsigned int depth, void* arg);
void *arg);
/* Insert a DER CRL into the CRL cache, and take ownership of it. /* Insert a DER CRL into the CRL cache, and take ownership of it.
* *
@ -323,7 +310,7 @@ void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
* the same encoding. To facilitate X.500 name matching, a canonicalized * the same encoding. To facilitate X.500 name matching, a canonicalized
* encoding of the GeneralName should be used, if available. * encoding of the GeneralName should be used, if available.
*/ */
SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl, SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
const SECItem* canonicalizedName); const SECItem* canonicalizedName);
@ -336,15 +323,15 @@ struct NamedCRLCacheStr {
* and read by cert_FindCRLByGeneralName */ * and read by cert_FindCRLByGeneralName */
struct NamedCRLCacheEntryStr { struct NamedCRLCacheEntryStr {
SECItem* canonicalizedName; SECItem* canonicalizedName;
SECItem* crl; /* DER, kept only if CRL SECItem* crl; /* DER, kept only if CRL
* is successfully cached */ * is successfully cached */
PRBool inCRLCache; PRBool inCRLCache;
PRTime successfulInsertionTime; /* insertion time */ PRTime successfulInsertionTime; /* insertion time */
PRTime lastAttemptTime; /* time of last call to PRTime lastAttemptTime; /* time of last call to
cert_CacheCRLByGeneralName with this name */ cert_CacheCRLByGeneralName with this name */
PRBool badDER; /* ASN.1 error */ PRBool badDER; /* ASN.1 error */
PRBool dupe; /* matching DER CRL already in CRL cache */ PRBool dupe; /* matching DER CRL already in CRL cache */
PRBool unsupported; /* IDP, delta, any other reason */ PRBool unsupported; /* IDP, delta, any other reason */
}; };
typedef enum { typedef enum {
@ -355,12 +342,12 @@ typedef enum {
/* Returns detailed status of the cert(revStatus variable). Tells if /* Returns detailed status of the cert(revStatus variable). Tells if
* issuer cache has OriginFetchedWithTimeout crl in it. */ * issuer cache has OriginFetchedWithTimeout crl in it. */
SECStatus SECStatus cert_CheckCertRevocationStatus(CERTCertificate* cert,
cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer, CERTCertificate* issuer,
const SECItem* dp, PRTime t, void *wincx, const SECItem* dp, PRTime t,
CERTRevocationStatus *revStatus, void* wincx,
CERTCRLEntryReasonCode *revReason); CERTRevocationStatus* revStatus,
CERTCRLEntryReasonCode* revReason);
SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned); SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned);
@ -374,26 +361,21 @@ SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc,
SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc); SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc);
/* This is private for now. Maybe shoule be public. */ /* This is private for now. Maybe shoule be public. */
CERTGeneralName * CERTGeneralName* cert_GetSubjectAltNameList(const CERTCertificate* cert,
cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena); PLArenaPool* arena);
/* Count DNS names and IP addresses in a list of GeneralNames */ /* Count DNS names and IP addresses in a list of GeneralNames */
PRUint32 PRUint32 cert_CountDNSPatterns(CERTGeneralName* firstName);
cert_CountDNSPatterns(CERTGeneralName *firstName);
/* /*
* returns the trust status of the leaf certificate based on usage. * returns the trust status of the leaf certificate based on usage.
* If the leaf is explicitly untrusted, this function will fail and * If the leaf is explicitly untrusted, this function will fail and
* failedFlags will be set to the trust bit value that lead to the failure. * failedFlags will be set to the trust bit value that lead to the failure.
* If the leaf is trusted, isTrusted is set to true and the function returns * If the leaf is trusted, isTrusted is set to true and the function returns
* SECSuccess. This function does not check if the cert is fit for a * SECSuccess. This function does not check if the cert is fit for a
* particular usage. * particular usage.
*/ */
SECStatus SECStatus cert_CheckLeafTrust(CERTCertificate* cert, SECCertUsage usage,
cert_CheckLeafTrust(CERTCertificate *cert, unsigned int* failedFlags, PRBool* isTrusted);
SECCertUsage usage,
unsigned int *failedFlags,
PRBool *isTrusted);
#endif /* _CERTI_H_ */ #endif /* _CERTI_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -15,17 +15,15 @@
#include "secerr.h" #include "secerr.h"
SECStatus SECStatus
CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, SECItem *value)
SECItem *value)
{ {
return (cert_FindExtensionByOID (cert->extensions, oid, value)); return (cert_FindExtensionByOID(cert->extensions, oid, value));
} }
SECStatus SECStatus
CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value) CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value)
{ {
return (cert_FindExtension (cert->extensions, tag, value)); return (cert_FindExtension(cert->extensions, tag, value));
} }
static void static void
@ -34,13 +32,13 @@ SetExts(void *object, CERTCertExtension **exts)
CERTCertificate *cert = (CERTCertificate *)object; CERTCertificate *cert = (CERTCertificate *)object;
cert->extensions = exts; cert->extensions = exts;
DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); DER_SetUInteger(cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
} }
void * void *
CERT_StartCertExtensions(CERTCertificate *cert) CERT_StartCertExtensions(CERTCertificate *cert)
{ {
return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); return (cert_StartExtensions((void *)cert, cert->arena, SetExts));
} }
/* /*
@ -50,62 +48,60 @@ SECStatus
CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem) CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem)
{ {
return (CERT_FindBitStringExtension return (CERT_FindBitStringExtension(
(cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem)); cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
} }
/* /*
* get the value of a string type extension * get the value of a string type extension
*/ */
char * char *
CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag) CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag)
{ {
SECItem wrapperItem, tmpItem = {siBuffer,0}; SECItem wrapperItem, tmpItem = { siBuffer, 0 };
SECStatus rv; SECStatus rv;
PLArenaPool *arena = NULL; PLArenaPool *arena = NULL;
char *retstring = NULL; char *retstring = NULL;
wrapperItem.data = NULL; wrapperItem.data = NULL;
tmpItem.data = NULL; tmpItem.data = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( ! arena ) { if (!arena) {
goto loser; goto loser;
}
rv = cert_FindExtension(cert->extensions, oidtag,
&wrapperItem);
if ( rv != SECSuccess ) {
goto loser;
} }
rv = SEC_QuickDERDecodeItem(arena, &tmpItem, rv = cert_FindExtension(cert->extensions, oidtag, &wrapperItem);
SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem); if (rv != SECSuccess) {
goto loser;
if ( rv != SECSuccess ) {
goto loser;
} }
retstring = (char *)PORT_Alloc(tmpItem.len + 1 ); rv = SEC_QuickDERDecodeItem(
if ( retstring == NULL ) { arena, &tmpItem, SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
goto loser;
if (rv != SECSuccess) {
goto loser;
} }
retstring = (char *)PORT_Alloc(tmpItem.len + 1);
if (retstring == NULL) {
goto loser;
}
PORT_Memcpy(retstring, tmpItem.data, tmpItem.len); PORT_Memcpy(retstring, tmpItem.data, tmpItem.len);
retstring[tmpItem.len] = '\0'; retstring[tmpItem.len] = '\0';
loser: loser:
if ( arena ) { if (arena) {
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
}
if ( wrapperItem.data ) {
PORT_Free(wrapperItem.data);
} }
return(retstring); if (wrapperItem.data) {
PORT_Free(wrapperItem.data);
}
return (retstring);
} }
/* /*
@ -116,7 +112,7 @@ CERT_FindKeyUsageExtension(CERTCertificate *cert, SECItem *retItem)
{ {
return (CERT_FindBitStringExtension(cert->extensions, return (CERT_FindBitStringExtension(cert->extensions,
SEC_OID_X509_KEY_USAGE, retItem)); SEC_OID_X509_KEY_USAGE, retItem));
} }
/* /*
@ -127,24 +123,25 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
{ {
SECStatus rv; SECStatus rv;
SECItem encodedValue = {siBuffer, NULL, 0 }; SECItem encodedValue = { siBuffer, NULL, 0 };
SECItem decodedValue = {siBuffer, NULL, 0 }; SECItem decodedValue = { siBuffer, NULL, 0 };
rv = cert_FindExtension rv = cert_FindExtension(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID,
(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue); &encodedValue);
if (rv == SECSuccess) { if (rv == SECSuccess) {
PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); PLArenaPool *tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (tmpArena) { if (tmpArena) {
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue, rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
SEC_ASN1_GET(SEC_OctetStringTemplate), SEC_ASN1_GET(SEC_OctetStringTemplate),
&encodedValue); &encodedValue);
if (rv == SECSuccess) { if (rv == SECSuccess) {
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue); rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
} }
PORT_FreeArena(tmpArena, PR_FALSE); PORT_FreeArena(tmpArena, PR_FALSE);
} else { }
rv = SECFailure; else {
} rv = SECFailure;
}
} }
SECITEM_FreeItem(&encodedValue, PR_FALSE); SECITEM_FreeItem(&encodedValue, PR_FALSE);
return rv; return rv;
@ -152,7 +149,7 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
SECStatus SECStatus
CERT_FindBasicConstraintExten(CERTCertificate *cert, CERT_FindBasicConstraintExten(CERTCertificate *cert,
CERTBasicConstraints *value) CERTBasicConstraints *value)
{ {
SECItem encodedExtenValue; SECItem encodedExtenValue;
SECStatus rv; SECStatus rv;
@ -161,42 +158,42 @@ CERT_FindBasicConstraintExten(CERTCertificate *cert,
encodedExtenValue.len = 0; encodedExtenValue.len = 0;
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS, rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
&encodedExtenValue); &encodedExtenValue);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
return (rv); return (rv);
} }
rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue); rv = CERT_DecodeBasicConstraintValue(value, &encodedExtenValue);
/* free the raw extension data */ /* free the raw extension data */
PORT_Free(encodedExtenValue.data); PORT_Free(encodedExtenValue.data);
encodedExtenValue.data = NULL; encodedExtenValue.data = NULL;
return(rv); return (rv);
} }
CERTAuthKeyID * CERTAuthKeyID *
CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert) CERT_FindAuthKeyIDExten(PLArenaPool *arena, CERTCertificate *cert)
{ {
SECItem encodedExtenValue; SECItem encodedExtenValue;
SECStatus rv; SECStatus rv;
CERTAuthKeyID *ret; CERTAuthKeyID *ret;
encodedExtenValue.data = NULL; encodedExtenValue.data = NULL;
encodedExtenValue.len = 0; encodedExtenValue.len = 0;
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID, rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID,
&encodedExtenValue); &encodedExtenValue);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
return (NULL); return (NULL);
} }
ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); ret = CERT_DecodeAuthKeyID(arena, &encodedExtenValue);
PORT_Free(encodedExtenValue.data); PORT_Free(encodedExtenValue.data);
encodedExtenValue.data = NULL; encodedExtenValue.data = NULL;
return(ret); return (ret);
} }
SECStatus SECStatus
@ -207,9 +204,9 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
/* There is no extension, v1 or v2 certificate */ /* There is no extension, v1 or v2 certificate */
if (cert->extensions == NULL) { if (cert->extensions == NULL) {
return (SECSuccess); return (SECSuccess);
} }
keyUsage.data = NULL; keyUsage.data = NULL;
/* This code formerly ignored the Key Usage extension if it was /* This code formerly ignored the Key Usage extension if it was
@ -218,12 +215,13 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
*/ */
rv = CERT_FindKeyUsageExtension(cert, &keyUsage); rv = CERT_FindKeyUsageExtension(cert, &keyUsage);
if (rv == SECFailure) { if (rv == SECFailure) {
rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? rv = (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) ? SECSuccess
SECSuccess : SECFailure; : SECFailure;
} else if (!(keyUsage.data[0] & usage)) {
PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID);
rv = SECFailure;
} }
PORT_Free (keyUsage.data); else if (!(keyUsage.data[0] & usage)) {
PORT_SetError(SEC_ERROR_CERT_USAGES_INVALID);
rv = SECFailure;
}
PORT_Free(keyUsage.data);
return (rv); return (rv);
} }

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

@ -16,93 +16,93 @@
#include "secerr.h" #include "secerr.h"
#ifdef OLD #ifdef OLD
#include "ocspti.h" /* XXX a better extensions interface would not #include "ocspti.h" /* XXX a better extensions interface would not
* require knowledge of data structures of callers */ * require knowledge of data structures of callers */
#endif #endif
static CERTCertExtension * static CERTCertExtension *
GetExtension (CERTCertExtension **extensions, SECItem *oid) GetExtension(CERTCertExtension **extensions, SECItem *oid)
{ {
CERTCertExtension **exts; CERTCertExtension **exts;
CERTCertExtension *ext = NULL; CERTCertExtension *ext = NULL;
SECComparison comp; SECComparison comp;
exts = extensions; exts = extensions;
if (exts) {
while ( *exts ) {
ext = *exts;
comp = SECITEM_CompareItem(oid, &ext->id);
if ( comp == SECEqual )
break;
exts++; if (exts) {
} while (*exts) {
return (*exts ? ext : NULL); ext = *exts;
comp = SECITEM_CompareItem(oid, &ext->id);
if (comp == SECEqual)
break;
exts++;
}
return (*exts ? ext : NULL);
} }
return (NULL); return (NULL);
} }
SECStatus SECStatus
cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value) cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid,
SECItem *value)
{ {
CERTCertExtension *ext; CERTCertExtension *ext;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
ext = GetExtension (extensions, oid); ext = GetExtension(extensions, oid);
if (ext == NULL) { if (ext == NULL) {
PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND); PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
return (SECFailure); return (SECFailure);
} }
if (value) if (value)
rv = SECITEM_CopyItem(NULL, value, &ext->value); rv = SECITEM_CopyItem(NULL, value, &ext->value);
return (rv); return (rv);
} }
SECStatus SECStatus
CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical) CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag,
PRBool *isCritical)
{ {
CERTCertExtension *ext; CERTCertExtension *ext;
SECOidData *oid; SECOidData *oid;
if (!isCritical) if (!isCritical)
return (SECSuccess); return (SECSuccess);
/* find the extension in the extensions list */ /* find the extension in the extensions list */
oid = SECOID_FindOIDByTag((SECOidTag)tag); oid = SECOID_FindOIDByTag((SECOidTag)tag);
if ( !oid ) { if (!oid) {
return(SECFailure); return (SECFailure);
} }
ext = GetExtension (extensions, &oid->oid); ext = GetExtension(extensions, &oid->oid);
if (ext == NULL) { if (ext == NULL) {
PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND); PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
return (SECFailure); return (SECFailure);
} }
/* If the criticality is omitted, then it is false by default. /* If the criticality is omitted, then it is false by default.
ex->critical.data is NULL */ ex->critical.data is NULL */
if (ext->critical.data == NULL) if (ext->critical.data == NULL)
*isCritical = PR_FALSE; *isCritical = PR_FALSE;
else else
*isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE; *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
return (SECSuccess); return (SECSuccess);
} }
SECStatus SECStatus
cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value) cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
{ {
SECOidData *oid; SECOidData *oid;
oid = SECOID_FindOIDByTag((SECOidTag)tag); oid = SECOID_FindOIDByTag((SECOidTag)tag);
if ( !oid ) { if (!oid) {
return(SECFailure); return (SECFailure);
} }
return(cert_FindExtensionByOID(extensions, &oid->oid, value)); return (cert_FindExtensionByOID(extensions, &oid->oid, value));
} }
typedef struct _extNode { typedef struct _extNode {
struct _extNode *next; struct _extNode *next;
CERTCertExtension *ext; CERTCertExtension *ext;
@ -115,7 +115,7 @@ typedef struct {
PLArenaPool *arena; PLArenaPool *arena;
extNode *head; extNode *head;
int count; int count;
}extRec; } extRec;
/* /*
* cert_StartExtensions * cert_StartExtensions
@ -125,20 +125,20 @@ typedef struct {
*/ */
void * void *
cert_StartExtensions(void *owner, PLArenaPool *ownerArena, cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
void (*setExts)(void *object, CERTCertExtension **exts)) void (*setExts)(void *object, CERTCertExtension **exts))
{ {
PLArenaPool *arena; PLArenaPool *arena;
extRec *handle; extRec *handle;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( !arena ) { if (!arena) {
return(0); return (0);
} }
handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec)); handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
if ( !handle ) { if (!handle) {
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
return(0); return (0);
} }
handle->object = owner; handle->object = owner;
@ -148,8 +148,8 @@ cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
handle->arena = arena; handle->arena = arena;
handle->head = 0; handle->head = 0;
handle->count = 0; handle->count = 0;
return(handle); return (handle);
} }
static unsigned char hextrue = 0xff; static unsigned char hextrue = 0xff;
@ -158,77 +158,78 @@ static unsigned char hextrue = 0xff;
* Note - assumes that data pointed to by oid->data will not move * Note - assumes that data pointed to by oid->data will not move
*/ */
SECStatus SECStatus
CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value, CERT_AddExtensionByOID(void *exthandle, SECItem *oid, SECItem *value,
PRBool critical, PRBool copyData) PRBool critical, PRBool copyData)
{ {
CERTCertExtension *ext; CERTCertExtension *ext;
SECStatus rv; SECStatus rv;
extNode *node; extNode *node;
extRec *handle; extRec *handle;
handle = (extRec *)exthandle; handle = (extRec *)exthandle;
/* allocate space for extension and list node */ /* allocate space for extension and list node */
ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena, ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena,
sizeof(CERTCertExtension)); sizeof(CERTCertExtension));
if ( !ext ) { if (!ext) {
return(SECFailure); return (SECFailure);
} }
node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode)); node = (extNode *)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
if ( !node ) { if (!node) {
return(SECFailure); return (SECFailure);
} }
/* add to list */ /* add to list */
node->next = handle->head; node->next = handle->head;
handle->head = node; handle->head = node;
/* point to ext struct */ /* point to ext struct */
node->ext = ext; node->ext = ext;
/* the object ID of the extension */ /* the object ID of the extension */
ext->id = *oid; ext->id = *oid;
/* set critical field */ /* set critical field */
if ( critical ) { if (critical) {
ext->critical.data = (unsigned char*)&hextrue; ext->critical.data = (unsigned char *)&hextrue;
ext->critical.len = 1; ext->critical.len = 1;
} }
/* set the value */ /* set the value */
if ( copyData ) { if (copyData) {
rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value); rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
if ( rv ) { if (rv) {
return(SECFailure); return (SECFailure);
} }
} else { }
ext->value = *value; else {
ext->value = *value;
} }
handle->count++;
return(SECSuccess);
handle->count++;
return (SECSuccess);
} }
SECStatus SECStatus
CERT_AddExtension(void *exthandle, int idtag, SECItem *value, CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical,
PRBool critical, PRBool copyData) PRBool copyData)
{ {
SECOidData *oid; SECOidData *oid;
oid = SECOID_FindOIDByTag((SECOidTag)idtag); oid = SECOID_FindOIDByTag((SECOidTag)idtag);
if ( !oid ) { if (!oid) {
return(SECFailure); return (SECFailure);
} }
return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData)); return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical,
copyData));
} }
SECStatus SECStatus
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value, CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
PRBool critical, const SEC_ASN1Template *atemplate) PRBool critical, const SEC_ASN1Template *atemplate)
{ {
extRec *handle; extRec *handle;
SECItem *encitem; SECItem *encitem;
@ -236,45 +237,43 @@ CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
handle = (extRec *)exthandle; handle = (extRec *)exthandle;
encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate); encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
if ( encitem == NULL ) { if (encitem == NULL) {
return(SECFailure); return (SECFailure);
} }
return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE); return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
} }
void void
PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value) PrepareBitStringForEncoding(SECItem *bitsmap, SECItem *value)
{ {
unsigned char onebyte; unsigned char onebyte;
unsigned int i, len = 0; unsigned int i, len = 0;
/* to prevent warning on some platform at compile time */ /* to prevent warning on some platform at compile time */
onebyte = '\0'; onebyte = '\0';
/* Get the position of the right-most turn-on bit */ /* Get the position of the right-most turn-on bit */
for (i = 0; i < (value->len ) * 8; ++i) { for (i = 0; i < (value->len) * 8; ++i) {
if (i % 8 == 0) if (i % 8 == 0)
onebyte = value->data[i/8]; onebyte = value->data[i / 8];
if (onebyte & 0x80) if (onebyte & 0x80)
len = i; len = i;
onebyte <<= 1; onebyte <<= 1;
}
} bitsmap->data = value->data;
bitsmap->data = value->data; /* Add one here since we work with base 1 */
/* Add one here since we work with base 1 */ bitsmap->len = len + 1;
bitsmap->len = len + 1;
} }
SECStatus SECStatus
CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag, CERT_EncodeAndAddBitStrExtension(void *exthandle, int idtag, SECItem *value,
SECItem *value, PRBool critical) PRBool critical)
{ {
SECItem bitsmap; SECItem bitsmap;
PrepareBitStringForEncoding (&bitsmap, value); PrepareBitStringForEncoding(&bitsmap, value);
return (CERT_EncodeAndAddExtension return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical,
(exthandle, idtag, &bitsmap, critical, SEC_ASN1_GET(SEC_BitStringTemplate)));
SEC_ASN1_GET(SEC_BitStringTemplate)));
} }
SECStatus SECStatus
@ -284,53 +283,53 @@ CERT_FinishExtensions(void *exthandle)
extNode *node; extNode *node;
CERTCertExtension **exts; CERTCertExtension **exts;
SECStatus rv = SECFailure; SECStatus rv = SECFailure;
handle = (extRec *)exthandle; handle = (extRec *)exthandle;
/* allocate space for extensions array */ /* allocate space for extensions array */
exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *, exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
handle->count + 1); handle->count + 1);
if (exts == NULL) { if (exts == NULL) {
goto loser; goto loser;
} }
/* put extensions in owner object and update its version number */ /* put extensions in owner object and update its version number */
#ifdef OLD #ifdef OLD
switch (handle->type) { switch (handle->type) {
case CertificateExtensions: case CertificateExtensions:
handle->owner.cert->extensions = exts; handle->owner.cert->extensions = exts;
DER_SetUInteger (ownerArena, &(handle->owner.cert->version), DER_SetUInteger(ownerArena, &(handle->owner.cert->version),
SEC_CERTIFICATE_VERSION_3); SEC_CERTIFICATE_VERSION_3);
break; break;
case CrlExtensions: case CrlExtensions:
handle->owner.crl->extensions = exts; handle->owner.crl->extensions = exts;
DER_SetUInteger (ownerArena, &(handle->owner.crl->version), DER_SetUInteger(ownerArena, &(handle->owner.crl->version),
SEC_CRL_VERSION_2); SEC_CRL_VERSION_2);
break; break;
case OCSPRequestExtensions: case OCSPRequestExtensions:
handle->owner.request->tbsRequest->requestExtensions = exts; handle->owner.request->tbsRequest->requestExtensions = exts;
break; break;
case OCSPSingleRequestExtensions: case OCSPSingleRequestExtensions:
handle->owner.singleRequest->singleRequestExtensions = exts; handle->owner.singleRequest->singleRequestExtensions = exts;
break; break;
case OCSPResponseSingleExtensions: case OCSPResponseSingleExtensions:
handle->owner.singleResponse->singleExtensions = exts; handle->owner.singleResponse->singleExtensions = exts;
break; break;
} }
#endif #endif
handle->setExts(handle->object, exts); handle->setExts(handle->object, exts);
/* update the version number */ /* update the version number */
/* copy each extension pointer */ /* copy each extension pointer */
node = handle->head; node = handle->head;
while ( node ) { while (node) {
*exts = node->ext; *exts = node->ext;
node = node->next; node = node->next;
exts++; exts++;
} }
/* terminate the array of extensions */ /* terminate the array of extensions */
@ -352,14 +351,14 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
SECOidTag tag; SECOidTag tag;
extNode *node; extNode *node;
extRec *handle = exthandle; extRec *handle = exthandle;
if (!exthandle || !extensions) { if (!exthandle || !extensions) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
while ((ext = *extensions++) != NULL) { while ((ext = *extensions++) != NULL) {
tag = SECOID_FindOIDTag(&ext->id); tag = SECOID_FindOIDTag(&ext->id);
for (node=handle->head; node != NULL; node=node->next) { for (node = handle->head; node != NULL; node = node->next) {
if (tag == 0) { if (tag == 0) {
if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id)) if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
break; break;
@ -372,15 +371,15 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
} }
if (node == NULL) { if (node == NULL) {
PRBool critical = (ext->critical.len != 0 && PRBool critical = (ext->critical.len != 0 &&
ext->critical.data[ext->critical.len - 1] != 0); ext->critical.data[ext->critical.len - 1] != 0);
if (critical && tag == SEC_OID_UNKNOWN) { if (critical && tag == SEC_OID_UNKNOWN) {
PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
rv = SECFailure; rv = SECFailure;
break; break;
} }
/* add to list */ /* add to list */
rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value, rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value,
critical, PR_TRUE); critical, PR_TRUE);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
} }
@ -392,108 +391,107 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
* get the value of the Netscape Certificate Type Extension * get the value of the Netscape Certificate Type Extension
*/ */
SECStatus SECStatus
CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag, CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
SECItem *retItem) SECItem *retItem)
{ {
SECItem wrapperItem, tmpItem = {siBuffer,0}; SECItem wrapperItem, tmpItem = { siBuffer, 0 };
SECStatus rv; SECStatus rv;
PLArenaPool *arena = NULL; PLArenaPool *arena = NULL;
wrapperItem.data = NULL; wrapperItem.data = NULL;
tmpItem.data = NULL; tmpItem.data = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( ! arena ) { if (!arena) {
return(SECFailure); return (SECFailure);
} }
rv = cert_FindExtension(extensions, tag, &wrapperItem); rv = cert_FindExtension(extensions, tag, &wrapperItem);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
goto loser; goto loser;
} }
rv = SEC_QuickDERDecodeItem(arena, &tmpItem, rv = SEC_QuickDERDecodeItem(
SEC_ASN1_GET(SEC_BitStringTemplate), arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);
&wrapperItem);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
goto loser; goto loser;
} }
retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 ); retItem->data = (unsigned char *)PORT_Alloc((tmpItem.len + 7) >> 3);
if ( retItem->data == NULL ) { if (retItem->data == NULL) {
goto loser; goto loser;
} }
PORT_Memcpy(retItem->data, tmpItem.data, ( tmpItem.len + 7 ) >> 3); PORT_Memcpy(retItem->data, tmpItem.data, (tmpItem.len + 7) >> 3);
retItem->len = tmpItem.len; retItem->len = tmpItem.len;
rv = SECSuccess; rv = SECSuccess;
goto done; goto done;
loser: loser:
rv = SECFailure; rv = SECFailure;
done: done:
if ( arena ) { if (arena) {
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
}
if ( wrapperItem.data ) {
PORT_Free(wrapperItem.data);
} }
return(rv); if (wrapperItem.data) {
PORT_Free(wrapperItem.data);
}
return (rv);
} }
PRBool PRBool
cert_HasCriticalExtension (CERTCertExtension **extensions) cert_HasCriticalExtension(CERTCertExtension **extensions)
{ {
CERTCertExtension **exts; CERTCertExtension **exts;
CERTCertExtension *ext = NULL; CERTCertExtension *ext = NULL;
PRBool hasCriticalExten = PR_FALSE; PRBool hasCriticalExten = PR_FALSE;
exts = extensions; exts = extensions;
if (exts) { if (exts) {
while ( *exts ) { while (*exts) {
ext = *exts; ext = *exts;
/* If the criticality is omitted, it's non-critical */ /* If the criticality is omitted, it's non-critical */
if (ext->critical.data && ext->critical.data[0] == 0xff) { if (ext->critical.data && ext->critical.data[0] == 0xff) {
hasCriticalExten = PR_TRUE; hasCriticalExten = PR_TRUE;
break; break;
} }
exts++; exts++;
} }
} }
return (hasCriticalExten); return (hasCriticalExten);
} }
PRBool PRBool
cert_HasUnknownCriticalExten (CERTCertExtension **extensions) cert_HasUnknownCriticalExten(CERTCertExtension **extensions)
{ {
CERTCertExtension **exts; CERTCertExtension **exts;
CERTCertExtension *ext = NULL; CERTCertExtension *ext = NULL;
PRBool hasUnknownCriticalExten = PR_FALSE; PRBool hasUnknownCriticalExten = PR_FALSE;
exts = extensions; exts = extensions;
if (exts) { if (exts) {
while ( *exts ) { while (*exts) {
ext = *exts; ext = *exts;
/* If the criticality is omitted, it's non-critical. /* If the criticality is omitted, it's non-critical.
If an extension is critical, make sure that we know If an extension is critical, make sure that we know
how to process the extension. how to process the extension.
*/ */
if (ext->critical.data && ext->critical.data[0] == 0xff) { if (ext->critical.data && ext->critical.data[0] == 0xff) {
if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) { if (SECOID_KnownCertExtenOID(&ext->id) == PR_FALSE) {
hasUnknownCriticalExten = PR_TRUE; hasUnknownCriticalExten = PR_TRUE;
break; break;
} }
} }
exts++; exts++;
} }
} }
return (hasUnknownCriticalExten); return (hasUnknownCriticalExten);
} }

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

@ -7,7 +7,6 @@
* *
*/ */
#ifndef _CERTXUTL_H_ #ifndef _CERTXUTL_H_
#define _CERTXUTL_H_ #define _CERTXUTL_H_
@ -23,28 +22,23 @@ typedef enum {
} ExtensionsType; } ExtensionsType;
#endif #endif
extern PRBool extern PRBool cert_HasCriticalExtension(CERTCertExtension **extensions);
cert_HasCriticalExtension (CERTCertExtension **extensions);
extern SECStatus extern SECStatus CERT_FindBitStringExtension(CERTCertExtension **extensions,
CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag, SECItem *retItem);
int tag, SECItem *retItem); extern void *cert_StartExtensions(void *owner, PLArenaPool *arena,
extern void * void (*setExts)(void *object,
cert_StartExtensions (void *owner, PLArenaPool *arena, CERTCertExtension **exts));
void (*setExts)(void *object, CERTCertExtension **exts));
extern SECStatus extern SECStatus cert_FindExtension(CERTCertExtension **extensions, int tag,
cert_FindExtension (CERTCertExtension **extensions, int tag, SECItem *value); SECItem *value);
extern SECStatus extern SECStatus cert_FindExtensionByOID(CERTCertExtension **extensions,
cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value);
SECItem *oid, SECItem *value);
extern SECStatus extern SECStatus cert_GetExtenCriticality(CERTCertExtension **extensions,
cert_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical);
int tag, PRBool *isCritical);
extern PRBool extern PRBool cert_HasUnknownCriticalExten(CERTCertExtension **extensions);
cert_HasUnknownCriticalExten (CERTCertExtension **extensions);
#endif #endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -17,89 +17,76 @@ SEC_BEGIN_PROTOS
extern const SEC_ASN1Template CERT_GeneralNamesTemplate[]; extern const SEC_ASN1Template CERT_GeneralNamesTemplate[];
extern SECItem ** extern SECItem **cert_EncodeGeneralNames(PLArenaPool *arena,
cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names); CERTGeneralName *names);
extern CERTGeneralName * extern CERTGeneralName *cert_DecodeGeneralNames(PLArenaPool *arena,
cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName); SECItem **encodedGenName);
extern SECStatus extern SECStatus cert_DestroyGeneralNames(CERTGeneralName *name);
cert_DestroyGeneralNames(CERTGeneralName *name);
extern SECStatus extern SECStatus cert_EncodeNameConstraints(CERTNameConstraints *constraints,
cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena, PLArenaPool *arena, SECItem *dest);
SECItem *dest);
extern CERTNameConstraints * extern CERTNameConstraints *cert_DecodeNameConstraints(
cert_DecodeNameConstraints(PLArenaPool *arena, const SECItem *encodedConstraints); PLArenaPool *arena, const SECItem *encodedConstraints);
extern CERTGeneralName * extern CERTGeneralName *cert_CombineNamesLists(CERTGeneralName *list1,
cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2); CERTGeneralName *list2);
extern CERTNameConstraint * extern CERTNameConstraint *cert_CombineConstraintsLists(
cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2); CERTNameConstraint *list1, CERTNameConstraint *list2);
/*********************************************************************/ /*********************************************************************/
/* A thread safe implementation of General Names */ /* A thread safe implementation of General Names */
/*********************************************************************/ /*********************************************************************/
/* Destroy a Single CERTGeneralName */ /* Destroy a Single CERTGeneralName */
void void CERT_DestroyGeneralName(CERTGeneralName *name);
CERT_DestroyGeneralName(CERTGeneralName *name);
SECStatus SECStatus CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
SECStatus SECStatus CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *src);
CERTGeneralName *dest,
CERTGeneralName *src);
/* General Name Lists are a thread safe, reference counting layer to /* General Name Lists are a thread safe, reference counting layer to
* general names */ * general names */
/* Destroys a CERTGeneralNameList */ /* Destroys a CERTGeneralNameList */
void void CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
/* Creates a CERTGeneralNameList */ /* Creates a CERTGeneralNameList */
CERTGeneralNameList * CERTGeneralNameList *CERT_CreateGeneralNameList(CERTGeneralName *name);
CERT_CreateGeneralNameList(CERTGeneralName *name);
/* Compares two CERTGeneralNameList */ /* Compares two CERTGeneralNameList */
SECStatus SECStatus CERT_CompareGeneralNameLists(CERTGeneralNameList *a,
CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b); CERTGeneralNameList *b);
/* returns a copy of the first name of the type requested */ /* returns a copy of the first name of the type requested */
void * void *CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, CERTGeneralNameType type,
CERTGeneralNameType type, PLArenaPool *arena);
PLArenaPool *arena);
/* Adds a name to the tail of the list */ /* Adds a name to the tail of the list */
void void CERT_AddGeneralNameToList(CERTGeneralNameList *list,
CERT_AddGeneralNameToList(CERTGeneralNameList *list, CERTGeneralNameType type, void *data,
CERTGeneralNameType type, SECItem *oid);
void *data, SECItem *oid);
/* returns a duplicate of the CERTGeneralNameList */ /* returns a duplicate of the CERTGeneralNameList */
CERTGeneralNameList * CERTGeneralNameList *CERT_DupGeneralNameList(CERTGeneralNameList *list);
CERT_DupGeneralNameList(CERTGeneralNameList *list);
/* returns the number of CERTGeneralName objects in the doubly linked /* returns the number of CERTGeneralName objects in the doubly linked
** list of which *names is a member. ** list of which *names is a member.
*/ */
extern int extern int CERT_GetNamesLength(CERTGeneralName *names);
CERT_GetNamesLength(CERTGeneralName *names);
/************************************************************************/ /************************************************************************/
SECStatus SECStatus CERT_CompareNameSpace(CERTCertificate *cert,
CERT_CompareNameSpace(CERTCertificate *cert, CERTGeneralName *namesList,
CERTGeneralName *namesList, CERTCertificate **certsList,
CERTCertificate **certsList, PLArenaPool *reqArena,
PLArenaPool *reqArena, CERTCertificate **pBadCert);
CERTCertificate **pBadCert);
SEC_END_PROTOS SEC_END_PROTOS

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -4,7 +4,7 @@
#include "cert.h" #include "cert.h"
#include "secoid.h" #include "secoid.h"
#include "secder.h" /* XXX remove this when remove the DERTemplates */ #include "secder.h" /* XXX remove this when remove the DERTemplates */
#include "secasn1.h" #include "secasn1.h"
#include "secitem.h" #include "secitem.h"
#include <stdarg.h> #include <stdarg.h>
@ -12,29 +12,25 @@
#include "certi.h" #include "certi.h"
static const SEC_ASN1Template cert_AVATemplate[] = { static const SEC_ASN1Template cert_AVATemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAVA) },
0, NULL, sizeof(CERTAVA) }, { SEC_ASN1_OBJECT_ID, offsetof(CERTAVA, type) },
{ SEC_ASN1_OBJECT_ID, { SEC_ASN1_ANY, offsetof(CERTAVA, value) },
offsetof(CERTAVA,type), }, { 0 }
{ SEC_ASN1_ANY,
offsetof(CERTAVA,value), },
{ 0, }
}; };
const SEC_ASN1Template CERT_RDNTemplate[] = { const SEC_ASN1Template CERT_RDNTemplate[] = {
{ SEC_ASN1_SET_OF, { SEC_ASN1_SET_OF, offsetof(CERTRDN, avas), cert_AVATemplate,
offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) } sizeof(CERTRDN) }
}; };
static int static int
CountArray(void **array) CountArray(void **array)
{ {
int count = 0; int count = 0;
if (array) { if (array) {
while (*array++) { while (*array++) {
count++; count++;
} }
} }
return count; return count;
} }
@ -49,36 +45,37 @@ AddToArray(PLArenaPool *arena, void **array, void *element)
count = 0; count = 0;
ap = array; ap = array;
if (ap) { if (ap) {
while (*ap++) { while (*ap++) {
count++; count++;
} }
} }
if (array) { if (array) {
array = (void**) PORT_ArenaGrow(arena, array, array =
(count + 1) * sizeof(void *), (void **)PORT_ArenaGrow(arena, array, (count + 1) * sizeof(void *),
(count + 2) * sizeof(void *)); (count + 2) * sizeof(void *));
} else { }
array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *)); else {
array = (void **)PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
} }
if (array) { if (array) {
array[count] = element; array[count] = element;
array[count+1] = 0; array[count + 1] = 0;
} }
return array; return array;
} }
SECOidTag SECOidTag
CERT_GetAVATag(CERTAVA *ava) CERT_GetAVATag(CERTAVA *ava)
{ {
SECOidData *oid; SECOidData *oid;
if (!ava->type.data) return (SECOidTag)-1; if (!ava->type.data)
return (SECOidTag)-1;
oid = SECOID_FindOID(&ava->type); oid = SECOID_FindOID(&ava->type);
if ( oid ) { if (oid) {
return(oid->offset); return (oid->offset);
} }
return (SECOidTag)-1; return (SECOidTag)-1;
} }
@ -89,25 +86,25 @@ SetupAVAType(PLArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
unsigned char *oid; unsigned char *oid;
unsigned oidLen; unsigned oidLen;
unsigned char *cp; unsigned char *cp;
int maxLen; int maxLen;
SECOidData *oidrec; SECOidData *oidrec;
oidrec = SECOID_FindOIDByTag(type); oidrec = SECOID_FindOIDByTag(type);
if (oidrec == NULL) if (oidrec == NULL)
return SECFailure; return SECFailure;
oid = oidrec->oid.data; oid = oidrec->oid.data;
oidLen = oidrec->oid.len; oidLen = oidrec->oid.len;
maxLen = cert_AVAOidTagToMaxLen(type); maxLen = cert_AVAOidTagToMaxLen(type);
if (maxLen < 0) { if (maxLen < 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen); it->data = cp = (unsigned char *)PORT_ArenaAlloc(arena, oidLen);
if (cp == NULL) { if (cp == NULL) {
return SECFailure; return SECFailure;
} }
it->len = oidLen; it->len = oidLen;
PORT_Memcpy(cp, oid, oidLen); PORT_Memcpy(cp, oid, oidLen);
@ -123,65 +120,66 @@ SetupAVAValue(PLArenaPool *arena, int valueType, const SECItem *in,
unsigned valueLen, valueLenLen, total; unsigned valueLen, valueLenLen, total;
unsigned ucs4Len = 0, ucs4MaxLen; unsigned ucs4Len = 0, ucs4MaxLen;
value = in->data; value = in->data;
valueLen = in->len; valueLen = in->len;
switch (valueType) { switch (valueType) {
case SEC_ASN1_PRINTABLE_STRING: case SEC_ASN1_PRINTABLE_STRING:
case SEC_ASN1_IA5_STRING: case SEC_ASN1_IA5_STRING:
case SEC_ASN1_T61_STRING: case SEC_ASN1_T61_STRING:
case SEC_ASN1_UTF8_STRING: /* no conversion required */ case SEC_ASN1_UTF8_STRING: /* no conversion required */
break; break;
case SEC_ASN1_UNIVERSAL_STRING: case SEC_ASN1_UNIVERSAL_STRING:
ucs4MaxLen = valueLen * 6; ucs4MaxLen = valueLen * 6;
ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen); ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen, if (!ucs4Val ||
ucs4Val, ucs4MaxLen, &ucs4Len)) { !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen, ucs4Val,
PORT_SetError(SEC_ERROR_INVALID_ARGS); ucs4MaxLen, &ucs4Len)) {
return SECFailure; PORT_SetError(SEC_ERROR_INVALID_ARGS);
} return SECFailure;
value = ucs4Val; }
valueLen = ucs4Len; value = ucs4Val;
maxLen *= 4; valueLen = ucs4Len;
break; maxLen *= 4;
default: break;
PORT_SetError(SEC_ERROR_INVALID_ARGS); default:
return SECFailure; PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
} }
if (valueLen > maxLen) { if (valueLen > maxLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
valueLenLen = DER_LengthLength(valueLen); valueLenLen = DER_LengthLength(valueLen);
total = 1 + valueLenLen + valueLen; total = 1 + valueLenLen + valueLen;
cp = (PRUint8*)PORT_ArenaAlloc(arena, total); cp = (PRUint8 *)PORT_ArenaAlloc(arena, total);
if (!cp) { if (!cp) {
return SECFailure; return SECFailure;
} }
out->data = cp; out->data = cp;
out->len = total; out->len = total;
cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen); cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen);
PORT_Memcpy(cp, value, valueLen); PORT_Memcpy(cp, value, valueLen);
return SECSuccess; return SECSuccess;
} }
CERTAVA * CERTAVA *
CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem * OID, CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem *OID,
const SECItem * value) const SECItem *value)
{ {
CERTAVA *ava; CERTAVA *ava;
int rv; int rv;
ava = PORT_ArenaZNew(pool, CERTAVA); ava = PORT_ArenaZNew(pool, CERTAVA);
if (ava) { if (ava) {
rv = SECITEM_CopyItem(pool, &ava->type, OID); rv = SECITEM_CopyItem(pool, &ava->type, OID);
if (rv) if (rv)
return NULL; return NULL;
rv = SECITEM_CopyItem(pool, &ava->value, value); rv = SECITEM_CopyItem(pool, &ava->value, value);
if (rv) if (rv)
return NULL; return NULL;
} }
return ava; return ava;
} }
@ -194,18 +192,18 @@ CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, int valueType,
int rv; int rv;
unsigned maxLen; unsigned maxLen;
ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
if (ava) { if (ava) {
rv = SetupAVAType(arena, kind, &ava->type, &maxLen); rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
if (rv) { if (rv) {
/* Illegal AVA type */ /* Illegal AVA type */
return NULL; return NULL;
} }
rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen); rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
if (rv) { if (rv) {
/* Illegal value type */ /* Illegal value type */
return NULL; return NULL;
} }
} }
return ava; return ava;
} }
@ -216,7 +214,7 @@ CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind, int valueType, char *value)
SECItem item = { siBuffer, NULL, 0 }; SECItem item = { siBuffer, NULL, 0 };
item.data = (PRUint8 *)value; item.data = (PRUint8 *)value;
item.len = PORT_Strlen(value); item.len = PORT_Strlen(value);
return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item); return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item);
} }
@ -227,16 +225,18 @@ CERT_CopyAVA(PLArenaPool *arena, CERTAVA *from)
CERTAVA *ava; CERTAVA *ava;
int rv; int rv;
ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
if (ava) { if (ava) {
rv = SECITEM_CopyItem(arena, &ava->type, &from->type); rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
if (rv) goto loser; if (rv)
rv = SECITEM_CopyItem(arena, &ava->value, &from->value); goto loser;
if (rv) goto loser; rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
if (rv)
goto loser;
} }
return ava; return ava;
loser: loser:
return 0; return 0;
} }
@ -249,34 +249,34 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
unsigned count; unsigned count;
CERTAVA **avap; CERTAVA **avap;
rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN)); rdn = (CERTRDN *)PORT_ArenaAlloc(arena, sizeof(CERTRDN));
if (rdn) { if (rdn) {
/* Count number of avas going into the rdn */ /* Count number of avas going into the rdn */
count = 0; count = 0;
if (ava0) { if (ava0) {
count++; count++;
va_start(ap, ava0); va_start(ap, ava0);
while ((ava = va_arg(ap, CERTAVA*)) != 0) { while ((ava = va_arg(ap, CERTAVA *)) != 0) {
count++; count++;
} }
va_end(ap); va_end(ap);
} }
/* Now fill in the pointers */ /* Now fill in the pointers */
rdn->avas = avap = rdn->avas = avap =
(CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*)); (CERTAVA **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTAVA *));
if (!avap) { if (!avap) {
return 0; return 0;
} }
if (ava0) { if (ava0) {
*avap++ = ava0; *avap++ = ava0;
va_start(ap, ava0); va_start(ap, ava0);
while ((ava = va_arg(ap, CERTAVA*)) != 0) { while ((ava = va_arg(ap, CERTAVA *)) != 0) {
*avap++ = ava; *avap++ = ava;
} }
va_end(ap); va_end(ap);
} }
*avap++ = 0; *avap++ = 0;
} }
return rdn; return rdn;
} }
@ -284,7 +284,7 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
SECStatus SECStatus
CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava) CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
{ {
rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava); rdn->avas = (CERTAVA **)AddToArray(arena, (void **)rdn->avas, ava);
return rdn->avas ? SECSuccess : SECFailure; return rdn->avas ? SECSuccess : SECFailure;
} }
@ -297,20 +297,20 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
/* Copy each ava from from */ /* Copy each ava from from */
avas = from->avas; avas = from->avas;
if (avas) { if (avas) {
if (avas[0] == NULL) { if (avas[0] == NULL) {
rv = CERT_AddAVA(arena, to, NULL); rv = CERT_AddAVA(arena, to, NULL);
return rv; return rv;
} }
while ((fava = *avas++) != 0) { while ((fava = *avas++) != 0) {
tava = CERT_CopyAVA(arena, fava); tava = CERT_CopyAVA(arena, fava);
if (!tava) { if (!tava) {
rv = SECFailure; rv = SECFailure;
break; break;
} }
rv = CERT_AddAVA(arena, to, tava); rv = CERT_AddAVA(arena, to, tava);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
} }
} }
return rv; return rv;
} }
@ -318,8 +318,8 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
/************************************************************************/ /************************************************************************/
const SEC_ASN1Template CERT_NameTemplate[] = { const SEC_ASN1Template CERT_NameTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF, { SEC_ASN1_SEQUENCE_OF, offsetof(CERTName, rdns), CERT_RDNTemplate,
offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) } sizeof(CERTName) }
}; };
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate) SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
@ -333,71 +333,72 @@ CERT_CreateName(CERTRDN *rdn0, ...)
unsigned count; unsigned count;
CERTRDN **rdnp; CERTRDN **rdnp;
PLArenaPool *arena; PLArenaPool *arena;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( !arena ) { if (!arena) {
return(0); return (0);
} }
name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName)); name = (CERTName *)PORT_ArenaAlloc(arena, sizeof(CERTName));
if (name) { if (name) {
name->arena = arena; name->arena = arena;
/* Count number of RDNs going into the Name */
if (!rdn0) {
count = 0;
} else {
count = 1;
va_start(ap, rdn0);
while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
count++;
}
va_end(ap);
}
/* Allocate space (including space for terminal null ptr) */ /* Count number of RDNs going into the Name */
name->rdns = rdnp = if (!rdn0) {
(CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*)); count = 0;
if (!name->rdns) { }
goto loser; else {
} count = 1;
va_start(ap, rdn0);
while ((rdn = va_arg(ap, CERTRDN *)) != 0) {
count++;
}
va_end(ap);
}
/* Now fill in the pointers */ /* Allocate space (including space for terminal null ptr) */
if (count > 0) { name->rdns = rdnp =
*rdnp++ = rdn0; (CERTRDN **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN *));
va_start(ap, rdn0); if (!name->rdns) {
while ((rdn = va_arg(ap, CERTRDN*)) != 0) { goto loser;
*rdnp++ = rdn; }
}
va_end(ap);
}
/* null terminate the list */ /* Now fill in the pointers */
*rdnp++ = 0; if (count > 0) {
*rdnp++ = rdn0;
va_start(ap, rdn0);
while ((rdn = va_arg(ap, CERTRDN *)) != 0) {
*rdnp++ = rdn;
}
va_end(ap);
}
/* null terminate the list */
*rdnp++ = 0;
} }
return name; return name;
loser: loser:
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
return(0); return (0);
} }
void void
CERT_DestroyName(CERTName *name) CERT_DestroyName(CERTName *name)
{ {
if (name) if (name) {
{
PLArenaPool *arena = name->arena; PLArenaPool *arena = name->arena;
name->rdns = NULL; name->rdns = NULL;
name->arena = NULL; name->arena = NULL;
if (arena) PORT_FreeArena(arena, PR_FALSE); if (arena)
PORT_FreeArena(arena, PR_FALSE);
} }
} }
SECStatus SECStatus
CERT_AddRDN(CERTName *name, CERTRDN *rdn) CERT_AddRDN(CERTName *name, CERTRDN *rdn)
{ {
name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn); name->rdns = (CERTRDN **)AddToArray(name->arena, (void **)name->rdns, rdn);
return name->rdns ? SECSuccess : SECFailure; return name->rdns ? SECSuccess : SECFailure;
} }
@ -408,8 +409,8 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
if (!to || !from) { if (!to || !from) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
CERT_DestroyName(to); CERT_DestroyName(to);
@ -418,23 +419,23 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
/* Copy each rdn from from */ /* Copy each rdn from from */
rdns = from->rdns; rdns = from->rdns;
if (rdns) { if (rdns) {
if (rdns[0] == NULL) { if (rdns[0] == NULL) {
rv = CERT_AddRDN(to, NULL); rv = CERT_AddRDN(to, NULL);
return rv; return rv;
} }
while ((frdn = *rdns++) != NULL) { while ((frdn = *rdns++) != NULL) {
trdn = CERT_CreateRDN(arena, NULL); trdn = CERT_CreateRDN(arena, NULL);
if (!trdn) { if (!trdn) {
rv = SECFailure; rv = SECFailure;
break; break;
} }
rv = CERT_CopyRDN(arena, trdn, frdn); rv = CERT_CopyRDN(arena, trdn, frdn);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
rv = CERT_AddRDN(to, trdn); rv = CERT_AddRDN(to, trdn);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
} }
} }
return rv; return rv;
} }
@ -442,34 +443,36 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
/************************************************************************/ /************************************************************************/
static void static void
canonicalize(SECItem * foo) canonicalize(SECItem *foo)
{ {
int ch, lastch, len, src, dest; int ch, lastch, len, src, dest;
/* strip trailing whitespace. */ /* strip trailing whitespace. */
len = foo->len; len = foo->len;
while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || ch == '\t' ||
ch == '\t' || ch == '\r' || ch == '\n')) { ch == '\r' || ch == '\n')) {
len--; len--;
} }
src = 0; src = 0;
/* strip leading whitespace. */ /* strip leading whitespace. */
while (src < len && ((ch = foo->data[src]) == ' ' || while (src < len && ((ch = foo->data[src]) == ' ' || ch == '\t' ||
ch == '\t' || ch == '\r' || ch == '\n')) { ch == '\r' || ch == '\n')) {
src++; src++;
} }
dest = 0; lastch = ' '; dest = 0;
lastch = ' ';
while (src < len) { while (src < len) {
ch = foo->data[src++]; ch = foo->data[src++];
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
ch = ' '; ch = ' ';
if (ch == lastch) if (ch == lastch)
continue; continue;
} else if (ch >= 'A' && ch <= 'Z') { }
ch |= 0x20; /* downshift */ else if (ch >= 'A' && ch <= 'Z') {
} ch |= 0x20; /* downshift */
foo->data[dest++] = lastch = ch; }
foo->data[dest++] = lastch = ch;
} }
foo->len = dest; foo->len = dest;
} }
@ -479,14 +482,13 @@ SECComparison
CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b) CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b)
{ {
SECComparison rv = SECLessThan; SECComparison rv = SECLessThan;
SECItem * aVal = CERT_DecodeAVAValue(a); SECItem *aVal = CERT_DecodeAVAValue(a);
SECItem * bVal = CERT_DecodeAVAValue(b); SECItem *bVal = CERT_DecodeAVAValue(b);
if (aVal && aVal->len && aVal->data && if (aVal && aVal->len && aVal->data && bVal && bVal->len && bVal->data) {
bVal && bVal->len && bVal->data) { canonicalize(aVal);
canonicalize(aVal); canonicalize(bVal);
canonicalize(bVal); rv = SECITEM_CompareItem(aVal, bVal);
rv = SECITEM_CompareItem(aVal, bVal);
} }
SECITEM_FreeItem(aVal, PR_TRUE); SECITEM_FreeItem(aVal, PR_TRUE);
SECITEM_FreeItem(bVal, PR_TRUE); SECITEM_FreeItem(bVal, PR_TRUE);
@ -500,30 +502,31 @@ CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b)
rv = SECITEM_CompareItem(&a->type, &b->type); rv = SECITEM_CompareItem(&a->type, &b->type);
if (SECEqual != rv) if (SECEqual != rv)
return rv; /* Attribute types don't match. */ return rv; /* Attribute types don't match. */
/* Let's be optimistic. Maybe the values will just compare equal. */ /* Let's be optimistic. Maybe the values will just compare equal. */
rv = SECITEM_CompareItem(&a->value, &b->value); rv = SECITEM_CompareItem(&a->value, &b->value);
if (SECEqual == rv) if (SECEqual == rv)
return rv; /* values compared exactly. */ return rv; /* values compared exactly. */
if (a->value.len && a->value.data && b->value.len && b->value.data) { if (a->value.len && a->value.data && b->value.len && b->value.data) {
/* Here, the values did not match. /* Here, the values did not match.
** If the values had different encodings, convert them to the same ** If the values had different encodings, convert them to the same
** encoding and compare that way. ** encoding and compare that way.
*/ */
if (a->value.data[0] != b->value.data[0]) { if (a->value.data[0] != b->value.data[0]) {
/* encodings differ. Convert both to UTF-8 and compare. */ /* encodings differ. Convert both to UTF-8 and compare. */
SECItem * aVal = CERT_DecodeAVAValue(&a->value); SECItem *aVal = CERT_DecodeAVAValue(&a->value);
SECItem * bVal = CERT_DecodeAVAValue(&b->value); SECItem *bVal = CERT_DecodeAVAValue(&b->value);
if (aVal && aVal->len && aVal->data && if (aVal && aVal->len && aVal->data && bVal && bVal->len &&
bVal && bVal->len && bVal->data) { bVal->data) {
rv = SECITEM_CompareItem(aVal, bVal); rv = SECITEM_CompareItem(aVal, bVal);
} }
SECITEM_FreeItem(aVal, PR_TRUE); SECITEM_FreeItem(aVal, PR_TRUE);
SECITEM_FreeItem(bVal, PR_TRUE); SECITEM_FreeItem(bVal, PR_TRUE);
} else if (a->value.data[0] == 0x13) { /* both are printable strings. */ }
/* printable strings */ else if (a->value.data[0] == 0x13) { /* both are printable strings. */
rv = CERT_CompareDERPrintableStrings(&a->value, &b->value); /* printable strings */
} rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
}
} }
return rv; return rv;
} }
@ -543,23 +546,25 @@ CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b)
** Make sure array of ava's are the same length. If not, then we are ** Make sure array of ava's are the same length. If not, then we are
** not equal ** not equal
*/ */
ac = CountArray((void**) aavas); ac = CountArray((void **)aavas);
bc = CountArray((void**) bavas); bc = CountArray((void **)bavas);
if (ac < bc) return SECLessThan; if (ac < bc)
if (ac > bc) return SECGreaterThan; return SECLessThan;
if (ac > bc)
return SECGreaterThan;
while (NULL != (aava = *aavas++)) { while (NULL != (aava = *aavas++)) {
for (bavas = b->avas; NULL != (bava = *bavas++); ) { for (bavas = b->avas; NULL != (bava = *bavas++);) {
rv = SECITEM_CompareItem(&aava->type, &bava->type); rv = SECITEM_CompareItem(&aava->type, &bava->type);
if (SECEqual == rv) { if (SECEqual == rv) {
rv = CERT_CompareAVA(aava, bava); rv = CERT_CompareAVA(aava, bava);
if (SECEqual != rv) if (SECEqual != rv)
return rv; return rv;
break; break;
} }
} }
if (!bava) /* didn't find a match */ if (!bava) /* didn't find a match */
return SECGreaterThan; return SECGreaterThan;
} }
return rv; return rv;
} }
@ -579,19 +584,22 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
** Make sure array of rdn's are the same length. If not, then we are ** Make sure array of rdn's are the same length. If not, then we are
** not equal ** not equal
*/ */
ac = CountArray((void**) ardns); ac = CountArray((void **)ardns);
bc = CountArray((void**) brdns); bc = CountArray((void **)brdns);
if (ac < bc) return SECLessThan; if (ac < bc)
if (ac > bc) return SECGreaterThan; return SECLessThan;
if (ac > bc)
return SECGreaterThan;
for (;;) { for (;;) {
ardn = *ardns++; ardn = *ardns++;
brdn = *brdns++; brdn = *brdns++;
if (!ardn) { if (!ardn) {
break; break;
} }
rv = CERT_CompareRDN(ardn, brdn); rv = CERT_CompareRDN(ardn, brdn);
if (rv) return rv; if (rv)
return rv;
} }
return rv; return rv;
} }
@ -600,47 +608,47 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
SECItem * SECItem *
CERT_DecodeAVAValue(const SECItem *derAVAValue) CERT_DecodeAVAValue(const SECItem *derAVAValue)
{ {
SECItem *retItem; SECItem *retItem;
const SEC_ASN1Template *theTemplate = NULL; const SEC_ASN1Template *theTemplate = NULL;
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none; enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
SECItem avaValue = {siBuffer, 0}; SECItem avaValue = { siBuffer, 0 };
PLArenaPool *newarena = NULL; PLArenaPool *newarena = NULL;
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) { if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
} }
switch(derAVAValue->data[0]) { switch (derAVAValue->data[0]) {
case SEC_ASN1_UNIVERSAL_STRING: case SEC_ASN1_UNIVERSAL_STRING:
convert = conv_ucs4; convert = conv_ucs4;
theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate); theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate);
break; break;
case SEC_ASN1_IA5_STRING: case SEC_ASN1_IA5_STRING:
theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
break; break;
case SEC_ASN1_PRINTABLE_STRING: case SEC_ASN1_PRINTABLE_STRING:
theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate); theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate);
break; break;
case SEC_ASN1_T61_STRING: case SEC_ASN1_T61_STRING:
/* /*
* Per common practice, we're not decoding actual T.61, but instead * Per common practice, we're not decoding actual T.61, but instead
* treating T61-labeled strings as containing ISO-8859-1. * treating T61-labeled strings as containing ISO-8859-1.
*/ */
convert = conv_iso88591; convert = conv_iso88591;
theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate); theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate);
break; break;
case SEC_ASN1_BMP_STRING: case SEC_ASN1_BMP_STRING:
convert = conv_ucs2; convert = conv_ucs2;
theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate); theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
break; break;
case SEC_ASN1_UTF8_STRING: case SEC_ASN1_UTF8_STRING:
/* No conversion needed ! */ /* No conversion needed ! */
theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate); theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
break; break;
default: default:
PORT_SetError(SEC_ERROR_INVALID_AVA); PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL; return NULL;
} }
PORT_Memset(&avaValue, 0, sizeof(SECItem)); PORT_Memset(&avaValue, 0, sizeof(SECItem));
@ -648,51 +656,54 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
if (!newarena) { if (!newarena) {
return NULL; return NULL;
} }
if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) if (SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) !=
!= SECSuccess) { SECSuccess) {
PORT_FreeArena(newarena, PR_FALSE); PORT_FreeArena(newarena, PR_FALSE);
return NULL; return NULL;
} }
if (convert != conv_none) { if (convert != conv_none) {
unsigned int utf8ValLen = avaValue.len * 3; unsigned int utf8ValLen = avaValue.len * 3;
unsigned char *utf8Val = (unsigned char*) unsigned char *utf8Val =
PORT_ArenaZAlloc(newarena, utf8ValLen); (unsigned char *)PORT_ArenaZAlloc(newarena, utf8ValLen);
switch (convert) { switch (convert) {
case conv_ucs4: case conv_ucs4:
if(avaValue.len % 4 != 0 || if (avaValue.len % 4 != 0 ||
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data,
utf8Val, utf8ValLen, &utf8ValLen)) { avaValue.len, utf8Val, utf8ValLen,
PORT_FreeArena(newarena, PR_FALSE); &utf8ValLen)) {
PORT_SetError(SEC_ERROR_INVALID_AVA); PORT_FreeArena(newarena, PR_FALSE);
return NULL; PORT_SetError(SEC_ERROR_INVALID_AVA);
} return NULL;
break; }
case conv_ucs2: break;
if(avaValue.len % 2 != 0 || case conv_ucs2:
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, if (avaValue.len % 2 != 0 ||
utf8Val, utf8ValLen, &utf8ValLen)) { !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data,
PORT_FreeArena(newarena, PR_FALSE); avaValue.len, utf8Val, utf8ValLen,
PORT_SetError(SEC_ERROR_INVALID_AVA); &utf8ValLen)) {
return NULL; PORT_FreeArena(newarena, PR_FALSE);
} PORT_SetError(SEC_ERROR_INVALID_AVA);
break; return NULL;
case conv_iso88591: }
if(!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len, break;
utf8Val, utf8ValLen, &utf8ValLen)) { case conv_iso88591:
PORT_FreeArena(newarena, PR_FALSE); if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
PORT_SetError(SEC_ERROR_INVALID_AVA); utf8Val, utf8ValLen,
return NULL; &utf8ValLen)) {
} PORT_FreeArena(newarena, PR_FALSE);
break; PORT_SetError(SEC_ERROR_INVALID_AVA);
case conv_none: return NULL;
PORT_Assert(0); /* not reached */ }
break; break;
} case conv_none:
PORT_Assert(0); /* not reached */
avaValue.data = utf8Val; break;
avaValue.len = utf8ValLen; }
avaValue.data = utf8Val;
avaValue.len = utf8ValLen;
} }
retItem = SECITEM_DupItem(&avaValue); retItem = SECITEM_DupItem(&avaValue);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* /*
* X.509 v3 Subject Key Usage Extension * X.509 v3 Subject Key Usage Extension
* *
*/ */
@ -14,7 +14,7 @@
#include "secasn1t.h" #include "secasn1t.h"
#include "secasn1.h" #include "secasn1.h"
#include "secport.h" #include "secport.h"
#include "certt.h" #include "certt.h"
#include "genname.h" #include "genname.h"
#include "secerr.h" #include "secerr.h"
@ -24,105 +24,106 @@ SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
const SEC_ASN1Template CERTAuthKeyIDTemplate[] = { const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) }, { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
offsetof(CERTAuthKeyID,keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate)}, offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate}, offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
offsetof(CERTAuthKeyID,authCertSerialNumber), offsetof(CERTAuthKeyID, authCertSerialNumber),
SEC_ASN1_SUB(SEC_IntegerTemplate) }, SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 } { 0 }
}; };
SECStatus
CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
SECStatus CERT_EncodeAuthKeyID (PLArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue) SECItem *encodedValue)
{ {
SECStatus rv = SECFailure; SECStatus rv = SECFailure;
PORT_Assert (value); PORT_Assert(value);
PORT_Assert (arena); PORT_Assert(arena);
PORT_Assert (value->DERAuthCertIssuer == NULL); PORT_Assert(value->DERAuthCertIssuer == NULL);
PORT_Assert (encodedValue); PORT_Assert(encodedValue);
do { do {
/* If both of the authCertIssuer and the serial number exist, encode
the name first. Otherwise, it is an error if one exist and the other
is not.
*/
if (value->authCertIssuer) {
if (!value->authCertSerialNumber.data) {
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
break;
}
value->DERAuthCertIssuer = cert_EncodeGeneralNames /* If both of the authCertIssuer and the serial number exist, encode
(arena, value->authCertIssuer); the name first. Otherwise, it is an error if one exist and the other
if (!value->DERAuthCertIssuer) { is not.
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); */
break; if (value->authCertIssuer) {
} if (!value->authCertSerialNumber.data) {
} PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
else if (value->authCertSerialNumber.data) { break;
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); }
break;
}
if (SEC_ASN1EncodeItem (arena, encodedValue, value, value->DERAuthCertIssuer =
CERTAuthKeyIDTemplate) == NULL) cert_EncodeGeneralNames(arena, value->authCertIssuer);
break; if (!value->DERAuthCertIssuer) {
rv = SECSuccess; PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
break;
}
}
else if (value->authCertSerialNumber.data) {
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
break;
}
if (SEC_ASN1EncodeItem(arena, encodedValue, value,
CERTAuthKeyIDTemplate) == NULL)
break;
rv = SECSuccess;
} while (0); } while (0);
return(rv); return (rv);
} }
CERTAuthKeyID * CERTAuthKeyID *
CERT_DecodeAuthKeyID (PLArenaPool *arena, const SECItem *encodedValue) CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
{ {
CERTAuthKeyID * value = NULL; CERTAuthKeyID *value = NULL;
SECStatus rv = SECFailure; SECStatus rv = SECFailure;
void * mark; void *mark;
SECItem newEncodedValue; SECItem newEncodedValue;
PORT_Assert(arena);
PORT_Assert (arena);
do { do {
mark = PORT_ArenaMark (arena); mark = PORT_ArenaMark(arena);
value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value));
if (value == NULL) if (value == NULL)
break; break;
value->DERAuthCertIssuer = NULL; value->DERAuthCertIssuer = NULL;
/* copy the DER into the arena, since Quick DER returns data that points /* copy the DER into the arena, since Quick DER returns data that points
into the DER input, which may get freed by the caller */ into the DER input, which may get freed by the caller */
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
break; break;
} }
rv = SEC_QuickDERDecodeItem rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate,
(arena, value, CERTAuthKeyIDTemplate, &newEncodedValue); &newEncodedValue);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer); value->authCertIssuer =
if (value->authCertIssuer == NULL) cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer);
break; if (value->authCertIssuer == NULL)
break;
/* what if the general name contains other format but not URI ?
hl /* what if the general name contains other format but not URI ?
*/ hl
if ((value->authCertSerialNumber.data && !value->authCertIssuer) || */
(!value->authCertSerialNumber.data && value->authCertIssuer)){ if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); (!value->authCertSerialNumber.data && value->authCertIssuer)) {
break; PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
} break;
}
} while (0); } while (0);
if (rv != SECSuccess) { if (rv != SECSuccess) {
PORT_ArenaRelease (arena, mark); PORT_ArenaRelease(arena, mark);
return ((CERTAuthKeyID *)NULL); return ((CERTAuthKeyID *)NULL);
} }
PORT_ArenaUnmark(arena, mark); PORT_ArenaUnmark(arena, mark);
return (value); return (value);
} }

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

@ -3,11 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* /*
* X.509 v3 Basic Constraints Extension * X.509 v3 Basic Constraints Extension
*/ */
#include "prtypes.h" #include "prtypes.h"
#include <limits.h> /* for LONG_MAX */ #include <limits.h> /* for LONG_MAX */
#include "seccomon.h" #include "seccomon.h"
#include "secdert.h" #include "secdert.h"
#include "secoidt.h" #include "secoidt.h"
@ -18,128 +18,132 @@
#include "prprf.h" #include "prprf.h"
#include "secerr.h" #include "secerr.h"
typedef struct EncodedContext{ typedef struct EncodedContext {
SECItem isCA; SECItem isCA;
SECItem pathLenConstraint; SECItem pathLenConstraint;
SECItem encodedValue; SECItem encodedValue;
PLArenaPool *arena; PLArenaPool *arena;
}EncodedContext; } EncodedContext;
static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = { static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(EncodedContext) },
0, NULL, sizeof(EncodedContext) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ offsetof(EncodedContext, isCA) },
offsetof(EncodedContext,isCA)},
{ SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
offsetof(EncodedContext,pathLenConstraint) }, offsetof(EncodedContext, pathLenConstraint) },
{ 0, } { 0 }
}; };
static unsigned char hexTrue = 0xff; static unsigned char hexTrue = 0xff;
static unsigned char hexFalse = 0x00; static unsigned char hexFalse = 0x00;
#define GEN_BREAK(status) rv = status; break; #define GEN_BREAK(status) \
rv = status; \
break;
SECStatus CERT_EncodeBasicConstraintValue SECStatus
(PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue) CERT_EncodeBasicConstraintValue(PLArenaPool *arena, CERTBasicConstraints *value,
SECItem *encodedValue)
{ {
EncodedContext encodeContext; EncodedContext encodeContext;
PLArenaPool *our_pool = NULL; PLArenaPool *our_pool = NULL;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
do { do {
PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
if (!value->isCA && value->pathLenConstraint >= 0) { if (!value->isCA && value->pathLenConstraint >= 0) {
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
GEN_BREAK (SECFailure); GEN_BREAK(SECFailure);
} }
encodeContext.arena = arena; encodeContext.arena = arena;
if (value->isCA == PR_TRUE) { if (value->isCA == PR_TRUE) {
encodeContext.isCA.data = &hexTrue ; encodeContext.isCA.data = &hexTrue;
encodeContext.isCA.len = 1; encodeContext.isCA.len = 1;
} }
/* If the pathLenConstraint is less than 0, then it should be /* If the pathLenConstraint is less than 0, then it should be
* omitted from the encoding. * omitted from the encoding.
*/ */
if (value->isCA && value->pathLenConstraint >= 0) { if (value->isCA && value->pathLenConstraint >= 0) {
our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (our_pool == NULL) { if (our_pool == NULL) {
PORT_SetError (SEC_ERROR_NO_MEMORY); PORT_SetError(SEC_ERROR_NO_MEMORY);
GEN_BREAK (SECFailure); GEN_BREAK(SECFailure);
} }
if (SEC_ASN1EncodeUnsignedInteger if (SEC_ASN1EncodeUnsignedInteger(
(our_pool, &encodeContext.pathLenConstraint, our_pool, &encodeContext.pathLenConstraint,
(unsigned long)value->pathLenConstraint) == NULL) { (unsigned long)value->pathLenConstraint) == NULL) {
PORT_SetError (SEC_ERROR_NO_MEMORY); PORT_SetError(SEC_ERROR_NO_MEMORY);
GEN_BREAK (SECFailure); GEN_BREAK(SECFailure);
} }
} }
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
CERTBasicConstraintsTemplate) == NULL) { CERTBasicConstraintsTemplate) == NULL) {
GEN_BREAK (SECFailure); GEN_BREAK(SECFailure);
} }
} while (0); } while (0);
if (our_pool) if (our_pool)
PORT_FreeArena (our_pool, PR_FALSE); PORT_FreeArena(our_pool, PR_FALSE);
return(rv); return (rv);
} }
SECStatus CERT_DecodeBasicConstraintValue SECStatus
(CERTBasicConstraints *value, const SECItem *encodedValue) CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
const SECItem *encodedValue)
{ {
EncodedContext decodeContext; EncodedContext decodeContext;
PLArenaPool *our_pool; PLArenaPool *our_pool;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
do { do {
PORT_Memset (&decodeContext, 0, sizeof (decodeContext)); PORT_Memset(&decodeContext, 0, sizeof(decodeContext));
/* initialize the value just in case we got "0x30 00", or when the /* initialize the value just in case we got "0x30 00", or when the
pathLenConstraint is omitted. pathLenConstraint is omitted.
*/ */
decodeContext.isCA.data =&hexFalse; decodeContext.isCA.data = &hexFalse;
decodeContext.isCA.len = 1; decodeContext.isCA.len = 1;
our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (our_pool == NULL) { if (our_pool == NULL) {
PORT_SetError (SEC_ERROR_NO_MEMORY); PORT_SetError(SEC_ERROR_NO_MEMORY);
GEN_BREAK (SECFailure); GEN_BREAK(SECFailure);
} }
rv = SEC_QuickDERDecodeItem(our_pool, &decodeContext,
CERTBasicConstraintsTemplate, encodedValue);
if (rv == SECFailure)
break;
value->isCA = decodeContext.isCA.data
? (PRBool)(decodeContext.isCA.data[0] != 0)
: PR_FALSE;
if (decodeContext.pathLenConstraint.data == NULL) {
/* if the pathLenConstraint is not encoded, and the current setting
is CA, then the pathLenConstraint should be set to a negative
number
for unlimited certificate path.
*/
if (value->isCA)
value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
}
else if (value->isCA) {
long len = DER_GetInteger(&decodeContext.pathLenConstraint);
if (len < 0 || len == LONG_MAX) {
PORT_SetError(SEC_ERROR_BAD_DER);
GEN_BREAK(SECFailure);
}
value->pathLenConstraint = len;
}
else {
/* here we get an error where the subject is not a CA, but
the pathLenConstraint is set */
PORT_SetError(SEC_ERROR_BAD_DER);
GEN_BREAK(SECFailure);
break;
}
rv = SEC_QuickDERDecodeItem
(our_pool, &decodeContext, CERTBasicConstraintsTemplate, encodedValue);
if (rv == SECFailure)
break;
value->isCA = decodeContext.isCA.data
? (PRBool)(decodeContext.isCA.data[0] != 0)
: PR_FALSE;
if (decodeContext.pathLenConstraint.data == NULL) {
/* if the pathLenConstraint is not encoded, and the current setting
is CA, then the pathLenConstraint should be set to a negative number
for unlimited certificate path.
*/
if (value->isCA)
value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
} else if (value->isCA) {
long len = DER_GetInteger (&decodeContext.pathLenConstraint);
if (len < 0 || len == LONG_MAX) {
PORT_SetError (SEC_ERROR_BAD_DER);
GEN_BREAK (SECFailure);
}
value->pathLenConstraint = len;
} else {
/* here we get an error where the subject is not a CA, but
the pathLenConstraint is set */
PORT_SetError (SEC_ERROR_BAD_DER);
GEN_BREAK (SECFailure);
break;
}
} while (0); } while (0);
PORT_FreeArena (our_pool, PR_FALSE); PORT_FreeArena(our_pool, PR_FALSE);
return (rv); return (rv);
} }

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* /*
* X.509 Extension Encoding * X.509 Extension Encoding
*/ */
#include "prtypes.h" #include "prtypes.h"
@ -20,12 +20,10 @@
#include "secasn1.h" #include "secasn1.h"
#include "secerr.h" #include "secerr.h"
static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = { static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
{ SEC_ASN1_OCTET_STRING } { SEC_ASN1_OCTET_STRING }
}; };
static const SEC_ASN1Template CERTIA5TypeTemplate[] = { static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
{ SEC_ASN1_IA5_STRING } { SEC_ASN1_IA5_STRING }
}; };
@ -33,40 +31,34 @@ static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate) SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = { static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
0, NULL, sizeof(CERTPrivKeyUsagePeriod) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, offsetof(CERTPrivKeyUsagePeriod, notBefore),
offsetof(CERTPrivKeyUsagePeriod, notBefore), SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, offsetof(CERTPrivKeyUsagePeriod, notAfter),
offsetof(CERTPrivKeyUsagePeriod, notAfter), SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate)}, { 0 }
{ 0, }
}; };
const SEC_ASN1Template CERTAltNameTemplate[] = { const SEC_ASN1Template CERTAltNameTemplate[] = {
{ SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName), { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
CERT_GeneralNamesTemplate} CERT_GeneralNamesTemplate }
}; };
const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = { const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthInfoAccess) },
0, NULL, sizeof(CERTAuthInfoAccess) }, { SEC_ASN1_OBJECT_ID, offsetof(CERTAuthInfoAccess, method) },
{ SEC_ASN1_OBJECT_ID, { SEC_ASN1_ANY, offsetof(CERTAuthInfoAccess, derLocation) },
offsetof(CERTAuthInfoAccess, method) }, { 0 }
{ SEC_ASN1_ANY,
offsetof(CERTAuthInfoAccess, derLocation) },
{ 0, }
}; };
const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = { const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate } { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
}; };
SECStatus
SECStatus CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
SECItem *encodedValue) SECItem *encodedValue)
{ {
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
@ -75,27 +67,26 @@ CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
if (SEC_ASN1EncodeItem (arena, encodedValue, srcString, if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
CERTSubjectKeyIDTemplate) == NULL) { CERTSubjectKeyIDTemplate) == NULL) {
rv = SECFailure; rv = SECFailure;
} }
return(rv);
}
return (rv);
}
SECStatus SECStatus
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena, CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
CERTPrivKeyUsagePeriod *pkup, CERTPrivKeyUsagePeriod *pkup,
SECItem *encodedValue) SECItem *encodedValue)
{ {
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
if (SEC_ASN1EncodeItem (arena, encodedValue, pkup, if (SEC_ASN1EncodeItem(arena, encodedValue, pkup,
CERTPrivateKeyUsagePeriodTemplate) == NULL) { CERTPrivateKeyUsagePeriodTemplate) == NULL) {
rv = SECFailure; rv = SECFailure;
} }
return(rv); return (rv);
} }
CERTPrivKeyUsagePeriod * CERTPrivKeyUsagePeriod *
@ -107,63 +98,62 @@ CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
/* allocate the certificate policies structure */ /* allocate the certificate policies structure */
pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod); pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
if ( pPeriod == NULL ) { if (pPeriod == NULL) {
goto loser; goto loser;
} }
pPeriod->arena = arena; pPeriod->arena = arena;
/* copy the DER into the arena, since Quick DER returns data that points /* copy the DER into the arena, since Quick DER returns data that points
into the DER input, which may get freed by the caller */ into the DER input, which may get freed by the caller */
rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
goto loser; goto loser;
} }
rv = SEC_QuickDERDecodeItem(arena, pPeriod, rv = SEC_QuickDERDecodeItem(
CERTPrivateKeyUsagePeriodTemplate, arena, pPeriod, CERTPrivateKeyUsagePeriodTemplate, &newExtnValue);
&newExtnValue); if (rv != SECSuccess) {
if ( rv != SECSuccess ) { goto loser;
goto loser;
} }
return pPeriod; return pPeriod;
loser: loser:
return NULL; return NULL;
} }
SECStatus
SECStatus CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue) SECItem *encodedValue)
{ {
SECItem encodeContext; SECItem encodeContext;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
if (value != NULL) { if (value != NULL) {
encodeContext.data = (unsigned char *)value; encodeContext.data = (unsigned char *)value;
encodeContext.len = strlen(value); encodeContext.len = strlen(value);
} }
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
CERTIA5TypeTemplate) == NULL) { CERTIA5TypeTemplate) == NULL) {
rv = SECFailure; rv = SECFailure;
} }
return(rv); return (rv);
} }
SECStatus SECStatus
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue) CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
SECItem *encodedValue)
{ {
SECItem **encodedGenName; SECItem **encodedGenName;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
encodedGenName = cert_EncodeGeneralNames(arena, value); encodedGenName = cert_EncodeGeneralNames(arena, value);
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName, if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
CERT_GeneralNamesTemplate) == NULL) { CERT_GeneralNamesTemplate) == NULL) {
rv = SECFailure; rv = SECFailure;
} }
return rv; return rv;
@ -172,9 +162,9 @@ CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECIte
CERTGeneralName * CERTGeneralName *
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName) CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
{ {
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
CERTAltNameEncodedContext encodedContext; CERTAltNameEncodedContext encodedContext;
SECItem* newEncodedAltName; SECItem *newEncodedAltName;
if (!reqArena) { if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -188,14 +178,13 @@ CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
encodedContext.encodedGenName = NULL; encodedContext.encodedGenName = NULL;
PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext)); PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext, rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
CERT_GeneralNamesTemplate, newEncodedAltName); CERT_GeneralNamesTemplate, newEncodedAltName);
if (rv == SECFailure) { if (rv == SECFailure) {
goto loser; goto loser;
} }
if (encodedContext.encodedGenName && encodedContext.encodedGenName[0]) if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
return cert_DecodeGeneralNames(reqArena, return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
encodedContext.encodedGenName);
/* Extension contained an empty GeneralNames sequence */ /* Extension contained an empty GeneralNames sequence */
/* Treat as extension not found */ /* Treat as extension not found */
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
@ -203,35 +192,32 @@ loser:
return NULL; return NULL;
} }
SECStatus SECStatus
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena, CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
CERTNameConstraints *value, CERTNameConstraints *value,
SECItem *encodedValue) SECItem *encodedValue)
{ {
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
rv = cert_EncodeNameConstraints(value, arena, encodedValue); rv = cert_EncodeNameConstraints(value, arena, encodedValue);
return rv; return rv;
} }
CERTNameConstraints * CERTNameConstraints *
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena, CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
const SECItem *encodedConstraints) const SECItem *encodedConstraints)
{ {
return cert_DecodeNameConstraints(arena, encodedConstraints); return cert_DecodeNameConstraints(arena, encodedConstraints);
} }
CERTAuthInfoAccess ** CERTAuthInfoAccess **
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena, CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
const SECItem *encodedExtension) const SECItem *encodedExtension)
{ {
CERTAuthInfoAccess **info = NULL; CERTAuthInfoAccess **info = NULL;
SECStatus rv; SECStatus rv;
int i; int i;
SECItem* newEncodedExtension; SECItem *newEncodedExtension;
if (!reqArena) { if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -243,24 +229,22 @@ CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
return NULL; return NULL;
} }
rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate, rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
newEncodedExtension); newEncodedExtension);
if (rv != SECSuccess || info == NULL) { if (rv != SECSuccess || info == NULL) {
return NULL; return NULL;
} }
for (i = 0; info[i] != NULL; i++) { for (i = 0; info[i] != NULL; i++) {
info[i]->location = CERT_DecodeGeneralName(reqArena, info[i]->location =
&(info[i]->derLocation), CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
NULL);
} }
return info; return info;
} }
SECStatus SECStatus
CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
CERTAuthInfoAccess **info, SECItem *dest)
SECItem *dest)
{ {
SECItem *dummy; SECItem *dummy;
int i; int i;
@ -268,19 +252,18 @@ CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
PORT_Assert(info != NULL); PORT_Assert(info != NULL);
PORT_Assert(dest != NULL); PORT_Assert(dest != NULL);
if (info == NULL || dest == NULL) { if (info == NULL || dest == NULL) {
return SECFailure; return SECFailure;
} }
for (i = 0; info[i] != NULL; i++) { for (i = 0; info[i] != NULL; i++) {
if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation), if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
arena) == NULL) arena) == NULL)
/* Note that this may leave some of the locations filled in. */ /* Note that this may leave some of the locations filled in. */
return SECFailure; return SECFailure;
} }
dummy = SEC_ASN1EncodeItem(arena, dest, &info, dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
CERTAuthInfoAccessTemplate);
if (dummy == NULL) { if (dummy == NULL) {
return SECFailure; return SECFailure;
} }
return SECSuccess; return SECSuccess;
} }

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

@ -10,27 +10,21 @@ typedef struct CERTAltNameEncodedContextStr {
SECItem **encodedGenName; SECItem **encodedGenName;
} CERTAltNameEncodedContext; } CERTAltNameEncodedContext;
SEC_BEGIN_PROTOS SEC_BEGIN_PROTOS
extern SECStatus extern SECStatus CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena, CERTPrivKeyUsagePeriod *pkup,
CERTPrivKeyUsagePeriod *pkup, SECItem *encodedValue);
SECItem *encodedValue);
extern SECStatus extern SECStatus CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena, CERTNameConstraints *value,
CERTNameConstraints *value, SECItem *encodedValue);
SECItem *encodedValue);
extern SECStatus extern SECStatus CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue);
SECItem *encodedValue);
SECStatus SECStatus cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
CERTAuthInfoAccess **info, SECItem *dest);
SECItem *dest);
SEC_END_PROTOS SEC_END_PROTOS
#endif #endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -22,31 +22,33 @@ static char *hex = "0123456789ABCDEF";
/* /*
** Convert a der-encoded integer to a hex printable string form ** Convert a der-encoded integer to a hex printable string form
*/ */
char *CERT_Hexify (SECItem *i, int do_colon) char *
CERT_Hexify(SECItem *i, int do_colon)
{ {
unsigned char *cp, *end; unsigned char *cp, *end;
char *rv, *o; char *rv, *o;
if (!i->len) { if (!i->len) {
return PORT_Strdup("00"); return PORT_Strdup("00");
} }
rv = o = (char*) PORT_Alloc(i->len * 3); rv = o = (char *)PORT_Alloc(i->len * 3);
if (!rv) return rv; if (!rv)
return rv;
cp = i->data; cp = i->data;
end = cp + i->len; end = cp + i->len;
while (cp < end) { while (cp < end) {
unsigned char ch = *cp++; unsigned char ch = *cp++;
*o++ = hex[(ch >> 4) & 0xf]; *o++ = hex[(ch >> 4) & 0xf];
*o++ = hex[ch & 0xf]; *o++ = hex[ch & 0xf];
if (cp != end) { if (cp != end) {
if (do_colon) { if (do_colon) {
*o++ = ':'; *o++ = ':';
} }
} }
} }
*o = 0; /* Null terminate the string */ *o = 0; /* Null terminate the string */
return rv; return rv;
} }
@ -58,132 +60,132 @@ char *CERT_Hexify (SECItem *i, int do_colon)
#define MAX_OUS 20 #define MAX_OUS 20
#define MAX_DC MAX_OUS #define MAX_DC MAX_OUS
char *
char *CERT_FormatName (CERTName *name) CERT_FormatName(CERTName *name)
{ {
CERTRDN** rdns; CERTRDN **rdns;
CERTRDN * rdn; CERTRDN *rdn;
CERTAVA** avas; CERTAVA **avas;
CERTAVA* ava; CERTAVA *ava;
char * buf = 0; char *buf = 0;
char * tmpbuf = 0; char *tmpbuf = 0;
SECItem * cn = 0; SECItem *cn = 0;
SECItem * email = 0; SECItem *email = 0;
SECItem * org = 0; SECItem *org = 0;
SECItem * loc = 0; SECItem *loc = 0;
SECItem * state = 0; SECItem *state = 0;
SECItem * country = 0; SECItem *country = 0;
SECItem * dq = 0; SECItem *dq = 0;
unsigned len = 0; unsigned len = 0;
int tag; int tag;
int i; int i;
int ou_count = 0; int ou_count = 0;
int dc_count = 0; int dc_count = 0;
PRBool first; PRBool first;
SECItem * orgunit[MAX_OUS]; SECItem *orgunit[MAX_OUS];
SECItem * dc[MAX_DC]; SECItem *dc[MAX_DC];
/* Loop over name components and gather the interesting ones */ /* Loop over name components and gather the interesting ones */
rdns = name->rdns; rdns = name->rdns;
while ((rdn = *rdns++) != 0) { while ((rdn = *rdns++) != 0) {
avas = rdn->avas; avas = rdn->avas;
while ((ava = *avas++) != 0) { while ((ava = *avas++) != 0) {
tag = CERT_GetAVATag(ava); tag = CERT_GetAVATag(ava);
switch(tag) { switch (tag) {
case SEC_OID_AVA_COMMON_NAME: case SEC_OID_AVA_COMMON_NAME:
if (cn) { if (cn) {
break; break;
} }
cn = CERT_DecodeAVAValue(&ava->value); cn = CERT_DecodeAVAValue(&ava->value);
if (!cn) { if (!cn) {
goto loser; goto loser;
} }
len += cn->len; len += cn->len;
break; break;
case SEC_OID_AVA_COUNTRY_NAME: case SEC_OID_AVA_COUNTRY_NAME:
if (country) { if (country) {
break; break;
} }
country = CERT_DecodeAVAValue(&ava->value); country = CERT_DecodeAVAValue(&ava->value);
if (!country) { if (!country) {
goto loser; goto loser;
} }
len += country->len; len += country->len;
break; break;
case SEC_OID_AVA_LOCALITY: case SEC_OID_AVA_LOCALITY:
if (loc) { if (loc) {
break; break;
} }
loc = CERT_DecodeAVAValue(&ava->value); loc = CERT_DecodeAVAValue(&ava->value);
if (!loc) { if (!loc) {
goto loser; goto loser;
} }
len += loc->len; len += loc->len;
break; break;
case SEC_OID_AVA_STATE_OR_PROVINCE: case SEC_OID_AVA_STATE_OR_PROVINCE:
if (state) { if (state) {
break; break;
} }
state = CERT_DecodeAVAValue(&ava->value); state = CERT_DecodeAVAValue(&ava->value);
if (!state) { if (!state) {
goto loser; goto loser;
} }
len += state->len; len += state->len;
break; break;
case SEC_OID_AVA_ORGANIZATION_NAME: case SEC_OID_AVA_ORGANIZATION_NAME:
if (org) { if (org) {
break; break;
} }
org = CERT_DecodeAVAValue(&ava->value); org = CERT_DecodeAVAValue(&ava->value);
if (!org) { if (!org) {
goto loser; goto loser;
} }
len += org->len; len += org->len;
break; break;
case SEC_OID_AVA_DN_QUALIFIER: case SEC_OID_AVA_DN_QUALIFIER:
if (dq) { if (dq) {
break; break;
} }
dq = CERT_DecodeAVAValue(&ava->value); dq = CERT_DecodeAVAValue(&ava->value);
if (!dq) { if (!dq) {
goto loser; goto loser;
} }
len += dq->len; len += dq->len;
break; break;
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
if (ou_count < MAX_OUS) { if (ou_count < MAX_OUS) {
orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value); orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
if (!orgunit[ou_count]) { if (!orgunit[ou_count]) {
goto loser; goto loser;
} }
len += orgunit[ou_count++]->len; len += orgunit[ou_count++]->len;
} }
break; break;
case SEC_OID_AVA_DC: case SEC_OID_AVA_DC:
if (dc_count < MAX_DC) { if (dc_count < MAX_DC) {
dc[dc_count] = CERT_DecodeAVAValue(&ava->value); dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
if (!dc[dc_count]) { if (!dc[dc_count]) {
goto loser; goto loser;
} }
len += dc[dc_count++]->len; len += dc[dc_count++]->len;
} }
break; break;
case SEC_OID_PKCS9_EMAIL_ADDRESS: case SEC_OID_PKCS9_EMAIL_ADDRESS:
case SEC_OID_RFC1274_MAIL: case SEC_OID_RFC1274_MAIL:
if (email) { if (email) {
break; break;
} }
email = CERT_DecodeAVAValue(&ava->value); email = CERT_DecodeAVAValue(&ava->value);
if (!email) { if (!email) {
goto loser; goto loser;
} }
len += email->len; len += email->len;
break; break;
default: default:
break; break;
} }
} }
} }
/* XXX - add some for formatting */ /* XXX - add some for formatting */
@ -191,109 +193,108 @@ char *CERT_FormatName (CERTName *name)
/* allocate buffer */ /* allocate buffer */
buf = (char *)PORT_Alloc(len); buf = (char *)PORT_Alloc(len);
if ( !buf ) { if (!buf) {
goto loser; goto loser;
} }
tmpbuf = buf; tmpbuf = buf;
if ( cn ) { if (cn) {
PORT_Memcpy(tmpbuf, cn->data, cn->len); PORT_Memcpy(tmpbuf, cn->data, cn->len);
tmpbuf += cn->len; tmpbuf += cn->len;
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
if ( email ) { if (email) {
PORT_Memcpy(tmpbuf, email->data, email->len); PORT_Memcpy(tmpbuf, email->data, email->len);
tmpbuf += ( email->len ); tmpbuf += (email->len);
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
for (i=ou_count-1; i >= 0; i--) { for (i = ou_count - 1; i >= 0; i--) {
PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len); PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
tmpbuf += ( orgunit[i]->len ); tmpbuf += (orgunit[i]->len);
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
if ( dq ) { if (dq) {
PORT_Memcpy(tmpbuf, dq->data, dq->len); PORT_Memcpy(tmpbuf, dq->data, dq->len);
tmpbuf += ( dq->len ); tmpbuf += (dq->len);
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
if ( org ) { if (org) {
PORT_Memcpy(tmpbuf, org->data, org->len); PORT_Memcpy(tmpbuf, org->data, org->len);
tmpbuf += ( org->len ); tmpbuf += (org->len);
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
for (i=dc_count-1; i >= 0; i--) { for (i = dc_count - 1; i >= 0; i--) {
PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len); PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
tmpbuf += ( dc[i]->len ); tmpbuf += (dc[i]->len);
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
first = PR_TRUE; first = PR_TRUE;
if ( loc ) { if (loc) {
PORT_Memcpy(tmpbuf, loc->data, loc->len); PORT_Memcpy(tmpbuf, loc->data, loc->len);
tmpbuf += ( loc->len ); tmpbuf += (loc->len);
first = PR_FALSE; first = PR_FALSE;
} }
if ( state ) { if (state) {
if ( !first ) { if (!first) {
PORT_Memcpy(tmpbuf, COMMA, COMMALEN); PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
tmpbuf += COMMALEN; tmpbuf += COMMALEN;
} }
PORT_Memcpy(tmpbuf, state->data, state->len); PORT_Memcpy(tmpbuf, state->data, state->len);
tmpbuf += ( state->len ); tmpbuf += (state->len);
first = PR_FALSE; first = PR_FALSE;
} }
if ( country ) { if (country) {
if ( !first ) { if (!first) {
PORT_Memcpy(tmpbuf, COMMA, COMMALEN); PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
tmpbuf += COMMALEN; tmpbuf += COMMALEN;
} }
PORT_Memcpy(tmpbuf, country->data, country->len); PORT_Memcpy(tmpbuf, country->data, country->len);
tmpbuf += ( country->len ); tmpbuf += (country->len);
first = PR_FALSE; first = PR_FALSE;
} }
if ( !first ) { if (!first) {
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
tmpbuf += BREAKLEN; tmpbuf += BREAKLEN;
} }
*tmpbuf = 0; *tmpbuf = 0;
/* fall through and clean */ /* fall through and clean */
loser: loser:
if ( cn ) { if (cn) {
SECITEM_FreeItem(cn, PR_TRUE); SECITEM_FreeItem(cn, PR_TRUE);
} }
if ( email ) { if (email) {
SECITEM_FreeItem(email, PR_TRUE); SECITEM_FreeItem(email, PR_TRUE);
} }
for (i=ou_count-1; i >= 0; i--) { for (i = ou_count - 1; i >= 0; i--) {
SECITEM_FreeItem(orgunit[i], PR_TRUE); SECITEM_FreeItem(orgunit[i], PR_TRUE);
} }
if ( dq ) { if (dq) {
SECITEM_FreeItem(dq, PR_TRUE); SECITEM_FreeItem(dq, PR_TRUE);
} }
if ( org ) { if (org) {
SECITEM_FreeItem(org, PR_TRUE); SECITEM_FreeItem(org, PR_TRUE);
} }
for (i=dc_count-1; i >= 0; i--) { for (i = dc_count - 1; i >= 0; i--) {
SECITEM_FreeItem(dc[i], PR_TRUE); SECITEM_FreeItem(dc[i], PR_TRUE);
} }
if ( loc ) { if (loc) {
SECITEM_FreeItem(loc, PR_TRUE); SECITEM_FreeItem(loc, PR_TRUE);
} }
if ( state ) { if (state) {
SECITEM_FreeItem(state, PR_TRUE); SECITEM_FreeItem(state, PR_TRUE);
} }
if ( country ) { if (country) {
SECITEM_FreeItem(country, PR_TRUE); SECITEM_FreeItem(country, PR_TRUE);
} }
return(buf); return (buf);
} }

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

@ -14,10 +14,10 @@ SEC_ASN1_MKSUB(SEC_AnyTemplate)
const SEC_ASN1Template CERT_AttributeTemplate[] = { const SEC_ASN1Template CERT_AttributeTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTAttribute) }, 0, NULL, sizeof(CERTAttribute) },
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) }, { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue), { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
SEC_ASN1_SUB(SEC_AnyTemplate) }, SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 } { 0 }
}; };
@ -27,18 +27,18 @@ const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
const SEC_ASN1Template CERT_CertificateRequestTemplate[] = { const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTCertificateRequest) }, 0, NULL, sizeof(CERTCertificateRequest) },
{ SEC_ASN1_INTEGER, { SEC_ASN1_INTEGER,
offsetof(CERTCertificateRequest,version) }, offsetof(CERTCertificateRequest, version) },
{ SEC_ASN1_INLINE, { SEC_ASN1_INLINE,
offsetof(CERTCertificateRequest,subject), offsetof(CERTCertificateRequest, subject),
CERT_NameTemplate }, CERT_NameTemplate },
{ SEC_ASN1_INLINE, { SEC_ASN1_INLINE,
offsetof(CERTCertificateRequest,subjectPublicKeyInfo), offsetof(CERTCertificateRequest, subjectPublicKeyInfo),
CERT_SubjectPublicKeyInfoTemplate }, CERT_SubjectPublicKeyInfoTemplate },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(CERTCertificateRequest,attributes), offsetof(CERTCertificateRequest, attributes),
CERT_SetOfAttributeTemplate }, CERT_SetOfAttributeTemplate },
{ 0 } { 0 }
}; };
@ -46,25 +46,25 @@ SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)
CERTCertificate * CERTCertificate *
CERT_CreateCertificate(unsigned long serialNumber, CERT_CreateCertificate(unsigned long serialNumber,
CERTName *issuer, CERTName *issuer,
CERTValidity *validity, CERTValidity *validity,
CERTCertificateRequest *req) CERTCertificateRequest *req)
{ {
CERTCertificate *c; CERTCertificate *c;
int rv; int rv;
PLArenaPool *arena; PLArenaPool *arena;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( !arena ) { if (!arena) {
return(0); return (0);
} }
c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
if (!c) { if (!c) {
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
return 0; return 0;
} }
c->referenceCount = 1; c->referenceCount = 1;
@ -75,44 +75,50 @@ CERT_CreateCertificate(unsigned long serialNumber,
* If extensions are added, it will get changed as appropriate. * If extensions are added, it will get changed as appropriate.
*/ */
rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1); rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
if (rv) goto loser; if (rv)
goto loser;
rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber); rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
if (rv) goto loser; if (rv)
goto loser;
rv = CERT_CopyName(arena, &c->issuer, issuer); rv = CERT_CopyName(arena, &c->issuer, issuer);
if (rv) goto loser; if (rv)
goto loser;
rv = CERT_CopyValidity(arena, &c->validity, validity); rv = CERT_CopyValidity(arena, &c->validity, validity);
if (rv) goto loser; if (rv)
goto loser;
rv = CERT_CopyName(arena, &c->subject, &req->subject); rv = CERT_CopyName(arena, &c->subject, &req->subject);
if (rv) goto loser; if (rv)
goto loser;
rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo, rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
&req->subjectPublicKeyInfo); &req->subjectPublicKeyInfo);
if (rv) goto loser; if (rv)
goto loser;
return c; return c;
loser: loser:
CERT_DestroyCertificate(c); CERT_DestroyCertificate(c);
return 0; return 0;
} }
/************************************************************************/ /************************************************************************/
/* It's clear from the comments that the original author of this /* It's clear from the comments that the original author of this
* function expected the template for certificate requests to treat * function expected the template for certificate requests to treat
* the attributes as a SET OF ANY. This function expected to be * the attributes as a SET OF ANY. This function expected to be
* passed an array of SECItems each of which contained an already encoded * passed an array of SECItems each of which contained an already encoded
* Attribute. But the cert request template does not treat the * Attribute. But the cert request template does not treat the
* Attributes as a SET OF ANY, and AFAIK never has. Instead the template * Attributes as a SET OF ANY, and AFAIK never has. Instead the template
* encodes attributes as a SET OF xxxxxxx. That is, it expects to encode * encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
* each of the Attributes, not have them pre-encoded. Consequently an * each of the Attributes, not have them pre-encoded. Consequently an
* array of SECItems containing encoded Attributes is of no value to this * array of SECItems containing encoded Attributes is of no value to this
* function. But we cannot change the signature of this public function. * function. But we cannot change the signature of this public function.
* It must continue to take SECItems. * It must continue to take SECItems.
* *
* I have recoded this function so that each SECItem contains an * I have recoded this function so that each SECItem contains an
* encoded cert extension. The encoded cert extensions form the list for the * encoded cert extension. The encoded cert extensions form the list for the
* single attribute of the cert request. In this implementation there is at most * single attribute of the cert request. In this implementation there is at most
* one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST. * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
@ -120,95 +126,95 @@ CERT_CreateCertificate(unsigned long serialNumber,
CERTCertificateRequest * CERTCertificateRequest *
CERT_CreateCertificateRequest(CERTName *subject, CERT_CreateCertificateRequest(CERTName *subject,
CERTSubjectPublicKeyInfo *spki, CERTSubjectPublicKeyInfo *spki,
SECItem **attributes) SECItem **attributes)
{ {
CERTCertificateRequest *certreq; CERTCertificateRequest *certreq;
PLArenaPool *arena; PLArenaPool *arena;
CERTAttribute * attribute; CERTAttribute *attribute;
SECOidData * oidData; SECOidData *oidData;
SECStatus rv; SECStatus rv;
int i = 0; int i = 0;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) { if (arena == NULL) {
return NULL; return NULL;
} }
certreq = PORT_ArenaZNew(arena, CERTCertificateRequest); certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
if (!certreq) { if (!certreq) {
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
return NULL; return NULL;
} }
/* below here it is safe to goto loser */ /* below here it is safe to goto loser */
certreq->arena = arena; certreq->arena = arena;
rv = DER_SetUInteger(arena, &certreq->version, rv = DER_SetUInteger(arena, &certreq->version,
SEC_CERTIFICATE_REQUEST_VERSION); SEC_CERTIFICATE_REQUEST_VERSION);
if (rv != SECSuccess) if (rv != SECSuccess)
goto loser; goto loser;
rv = CERT_CopyName(arena, &certreq->subject, subject); rv = CERT_CopyName(arena, &certreq->subject, subject);
if (rv != SECSuccess) if (rv != SECSuccess)
goto loser; goto loser;
rv = SECKEY_CopySubjectPublicKeyInfo(arena, rv = SECKEY_CopySubjectPublicKeyInfo(arena,
&certreq->subjectPublicKeyInfo, &certreq->subjectPublicKeyInfo,
spki); spki);
if (rv != SECSuccess) if (rv != SECSuccess)
goto loser; goto loser;
certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2); certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute *, 2);
if(!certreq->attributes) if (!certreq->attributes)
goto loser; goto loser;
/* Copy over attribute information */ /* Copy over attribute information */
if (!attributes || !attributes[0]) { if (!attributes || !attributes[0]) {
/* /*
** Invent empty attribute information. According to the ** Invent empty attribute information. According to the
** pkcs#10 spec, attributes has this ASN.1 type: ** pkcs#10 spec, attributes has this ASN.1 type:
** **
** attributes [0] IMPLICIT Attributes ** attributes [0] IMPLICIT Attributes
** **
** Which means, we should create a NULL terminated list ** Which means, we should create a NULL terminated list
** with the first entry being NULL; ** with the first entry being NULL;
*/ */
certreq->attributes[0] = NULL; certreq->attributes[0] = NULL;
return certreq; return certreq;
} }
/* allocate space for attributes */ /* allocate space for attributes */
attribute = PORT_ArenaZNew(arena, CERTAttribute); attribute = PORT_ArenaZNew(arena, CERTAttribute);
if (!attribute) if (!attribute)
goto loser; goto loser;
oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST ); oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
PORT_Assert(oidData); PORT_Assert(oidData);
if (!oidData) if (!oidData)
goto loser; goto loser;
rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid); rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
if (rv != SECSuccess) if (rv != SECSuccess)
goto loser; goto loser;
for (i = 0; attributes[i] != NULL ; i++) for (i = 0; attributes[i] != NULL; i++)
; ;
attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1); attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i + 1);
if (!attribute->attrValue) if (!attribute->attrValue)
goto loser; goto loser;
/* copy attributes */ /* copy attributes */
for (i = 0; attributes[i]; i++) { for (i = 0; attributes[i]; i++) {
/* /*
** Attributes are a SetOf Attribute which implies ** Attributes are a SetOf Attribute which implies
** lexigraphical ordering. It is assumes that the ** lexigraphical ordering. It is assumes that the
** attributes are passed in sorted. If we need to ** attributes are passed in sorted. If we need to
** add functionality to sort them, there is an ** add functionality to sort them, there is an
** example in the PKCS 7 code. ** example in the PKCS 7 code.
*/ */
attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]); attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
if(!attribute->attrValue[i]) if (!attribute->attrValue[i])
goto loser; goto loser;
} }
certreq->attributes[0] = attribute; certreq->attributes[0] = attribute;
@ -224,7 +230,7 @@ void
CERT_DestroyCertificateRequest(CERTCertificateRequest *req) CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
{ {
if (req && req->arena) { if (req && req->arena) {
PORT_FreeArena(req->arena, PR_FALSE); PORT_FreeArena(req->arena, PR_FALSE);
} }
return; return;
} }
@ -241,11 +247,11 @@ setCRExt(void *o, CERTCertExtension **exts)
** attribute list by CERT_FinishCRAttributes(). ** attribute list by CERT_FinishCRAttributes().
*/ */
extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena, extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
void (*setExts)(void *object, CERTCertExtension **exts)); void (*setExts)(void *object, CERTCertExtension **exts));
void * void *
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req) CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
{ {
return (cert_StartExtensions ((void *)req, req->arena, setCRExt)); return (cert_StartExtensions((void *)req, req->arena, setCRExt));
} }
/* /*
@ -257,38 +263,39 @@ CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
*/ */
SECStatus SECStatus
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req) CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
{ SECItem *extlist; {
SECItem *extlist;
SECOidData *oidrec; SECOidData *oidrec;
CERTAttribute *attribute; CERTAttribute *attribute;
if (!req || !req->arena) { if (!req || !req->arena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
if (req->attributes == NULL || req->attributes[0] == NULL) if (req->attributes == NULL || req->attributes[0] == NULL)
return SECSuccess; return SECSuccess;
extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes, extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate)); SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
if (extlist == NULL) if (extlist == NULL)
return(SECFailure); return (SECFailure);
oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST); oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
if (oidrec == NULL) if (oidrec == NULL)
return SECFailure; return SECFailure;
/* now change the list of cert extensions into a list of attributes /* now change the list of cert extensions into a list of attributes
*/ */
req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute*, 2); req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute *, 2);
attribute = PORT_ArenaZNew(req->arena, CERTAttribute); attribute = PORT_ArenaZNew(req->arena, CERTAttribute);
if (req->attributes == NULL || attribute == NULL || if (req->attributes == NULL || attribute == NULL ||
SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) { SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure; return SECFailure;
} }
attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem*, 2); attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem *, 2);
if (attribute->attrValue == NULL) if (attribute->attrValue == NULL)
return SECFailure; return SECFailure;
@ -303,22 +310,22 @@ CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
SECStatus SECStatus
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req, CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
CERTCertExtension ***exts) CERTCertExtension ***exts)
{ {
if (req == NULL || exts == NULL) { if (req == NULL || exts == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (req->attributes == NULL || *req->attributes == NULL)
return SECSuccess;
if ((*req->attributes)->attrValue == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
return(SEC_ASN1DecodeItem(req->arena, exts, if (req->attributes == NULL || *req->attributes == NULL)
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate), return SECSuccess;
(*req->attributes)->attrValue[0]));
if ((*req->attributes)->attrValue == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
return (SEC_ASN1DecodeItem(req->arena, exts,
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
(*req->attributes)->attrValue[0]));
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -17,17 +17,15 @@
SECStatus SECStatus
CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value) CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value)
{ {
return (cert_FindExtensionByOID (crl->extensions, oid, value)); return (cert_FindExtensionByOID(crl->extensions, oid, value));
} }
SECStatus SECStatus
CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value) CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value)
{ {
return (cert_FindExtension (crl->extensions, tag, value)); return (cert_FindExtension(crl->extensions, tag, value));
} }
/* Callback to set extensions and adjust verison */ /* Callback to set extensions and adjust verison */
static void static void
SetCrlExts(void *object, CERTCertExtension **exts) SetCrlExts(void *object, CERTCertExtension **exts)
@ -35,13 +33,13 @@ SetCrlExts(void *object, CERTCertExtension **exts)
CERTCrl *crl = (CERTCrl *)object; CERTCrl *crl = (CERTCrl *)object;
crl->extensions = exts; crl->extensions = exts;
DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2); DER_SetUInteger(crl->arena, &crl->version, SEC_CRL_VERSION_2);
} }
void * void *
CERT_StartCRLExtensions(CERTCrl *crl) CERT_StartCRLExtensions(CERTCrl *crl)
{ {
return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts)); return (cert_StartExtensions((void *)crl, crl->arena, SetCrlExts));
} }
static void static void
@ -55,11 +53,12 @@ SetCrlEntryExts(void *object, CERTCertExtension **exts)
void * void *
CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry) CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry)
{ {
return (cert_StartExtensions (entry, crl->arena, SetCrlEntryExts)); return (cert_StartExtensions(entry, crl->arena, SetCrlEntryExts));
} }
SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl, SECStatus
SECItem *value) CERT_FindCRLNumberExten(PLArenaPool *arena, CERTCrl *crl,
SECItem *value)
{ {
SECItem encodedExtenValue; SECItem encodedExtenValue;
SECItem *tmpItem = NULL; SECItem *tmpItem = NULL;
@ -70,91 +69,94 @@ SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
encodedExtenValue.len = 0; encodedExtenValue.len = 0;
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER, rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER,
&encodedExtenValue); &encodedExtenValue);
if ( rv != SECSuccess ) if (rv != SECSuccess)
return (rv); return (rv);
mark = PORT_ArenaMark(arena); mark = PORT_ArenaMark(arena);
tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue); tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue);
if (tmpItem) { if (tmpItem) {
rv = SEC_QuickDERDecodeItem (arena, value, rv = SEC_QuickDERDecodeItem(arena, value,
SEC_ASN1_GET(SEC_IntegerTemplate), SEC_ASN1_GET(SEC_IntegerTemplate),
tmpItem); tmpItem);
} else { }
else {
rv = SECFailure; rv = SECFailure;
} }
PORT_Free (encodedExtenValue.data); PORT_Free(encodedExtenValue.data);
if (rv == SECFailure) { if (rv == SECFailure) {
PORT_ArenaRelease(arena, mark); PORT_ArenaRelease(arena, mark);
} else { }
else {
PORT_ArenaUnmark(arena, mark); PORT_ArenaUnmark(arena, mark);
} }
return (rv); return (rv);
} }
SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry, SECStatus
CERTCRLEntryReasonCode *value) CERT_FindCRLEntryReasonExten(CERTCrlEntry *crlEntry,
CERTCRLEntryReasonCode *value)
{ {
SECItem wrapperItem = {siBuffer,0}; SECItem wrapperItem = { siBuffer, 0 };
SECItem tmpItem = {siBuffer,0}; SECItem tmpItem = { siBuffer, 0 };
SECStatus rv; SECStatus rv;
PLArenaPool *arena = NULL; PLArenaPool *arena = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( ! arena ) { if (!arena) {
return(SECFailure); return (SECFailure);
} }
rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE, rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
&wrapperItem); &wrapperItem);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
goto loser; goto loser;
} }
rv = SEC_QuickDERDecodeItem(arena, &tmpItem, rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
SEC_ASN1_GET(SEC_EnumeratedTemplate), SEC_ASN1_GET(SEC_EnumeratedTemplate),
&wrapperItem); &wrapperItem);
if ( rv != SECSuccess ) { if (rv != SECSuccess) {
goto loser; goto loser;
} }
*value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem); *value = (CERTCRLEntryReasonCode)DER_GetInteger(&tmpItem);
loser: loser:
if ( arena ) { if (arena) {
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
} }
if ( wrapperItem.data ) { if (wrapperItem.data) {
PORT_Free(wrapperItem.data); PORT_Free(wrapperItem.data);
} }
return (rv); return (rv);
} }
SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value) SECStatus
CERT_FindInvalidDateExten(CERTCrl *crl, PRTime *value)
{ {
SECItem encodedExtenValue; SECItem encodedExtenValue;
SECItem decodedExtenValue = {siBuffer,0}; SECItem decodedExtenValue = { siBuffer, 0 };
SECStatus rv; SECStatus rv;
encodedExtenValue.data = decodedExtenValue.data = NULL; encodedExtenValue.data = decodedExtenValue.data = NULL;
encodedExtenValue.len = decodedExtenValue.len = 0; encodedExtenValue.len = decodedExtenValue.len = 0;
rv = cert_FindExtension rv = cert_FindExtension(crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue);
(crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue); if (rv != SECSuccess)
if ( rv != SECSuccess ) return (rv);
return (rv);
rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue, rv = SEC_ASN1DecodeItem(NULL, &decodedExtenValue,
SEC_ASN1_GET(SEC_GeneralizedTimeTemplate), SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
&encodedExtenValue); &encodedExtenValue);
if (rv == SECSuccess) if (rv == SECSuccess)
rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue); rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
PORT_Free (decodedExtenValue.data); PORT_Free(decodedExtenValue.data);
PORT_Free (encodedExtenValue.data); PORT_Free(encodedExtenValue.data);
return (rv); return (rv);
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -9,7 +9,6 @@
#ifndef _OCSP_H_ #ifndef _OCSP_H_
#define _OCSP_H_ #define _OCSP_H_
#include "plarena.h" #include "plarena.h"
#include "seccomon.h" #include "seccomon.h"
#include "secoidt.h" #include "secoidt.h"
@ -17,7 +16,6 @@
#include "certt.h" #include "certt.h"
#include "ocspt.h" #include "ocspt.h"
/************************************************************************/ /************************************************************************/
SEC_BEGIN_PROTOS SEC_BEGIN_PROTOS
@ -134,7 +132,7 @@ CERT_DisableOCSPChecking(CERTCertDBHandle *handle);
*/ */
extern SECStatus extern SECStatus
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle, CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
const char *url, const char *name); const char *url, const char *name);
/* /*
* FUNCTION: CERT_EnableOCSPDefaultResponder * FUNCTION: CERT_EnableOCSPDefaultResponder
@ -174,7 +172,7 @@ CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle);
/* If forcePost is set, OCSP requests will only be sent using the HTTP POST /* If forcePost is set, OCSP requests will only be sent using the HTTP POST
* method. When forcePost is not set, OCSP requests will be sent using the * method. When forcePost is not set, OCSP requests will be sent using the
* HTTP GET method, with a fallback to POST when we fail to receive a response * HTTP GET method, with a fallback to POST when we fail to receive a response
* and/or when we receive an uncacheable response like "Unknown." * and/or when we receive an uncacheable response like "Unknown."
* *
* The default is to use GET and fallback to POST. * The default is to use GET and fallback to POST.
*/ */
@ -191,7 +189,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
/* /*
* FUNCTION: CERT_CreateOCSPRequest * FUNCTION: CERT_CreateOCSPRequest
* Creates a CERTOCSPRequest, requesting the status of the certs in * Creates a CERTOCSPRequest, requesting the status of the certs in
* the given list. * the given list.
* INPUTS: * INPUTS:
* CERTCertList *certList * CERTCertList *certList
@ -203,7 +201,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
* to this routine), who knows about where the request(s) are being * to this routine), who knows about where the request(s) are being
* sent and whether there are any trusted responders in place. * sent and whether there are any trusted responders in place.
* PRTime time * PRTime time
* Indicates the time for which the certificate status is to be * Indicates the time for which the certificate status is to be
* determined -- this may be used in the search for the cert's issuer * determined -- this may be used in the search for the cert's issuer
* but has no effect on the request itself. * but has no effect on the request itself.
* PRBool addServiceLocator * PRBool addServiceLocator
@ -221,9 +219,9 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
* Other errors are low-level problems (no memory, bad database, etc.). * Other errors are low-level problems (no memory, bad database, etc.).
*/ */
extern CERTOCSPRequest * extern CERTOCSPRequest *
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time, CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
PRBool addServiceLocator, PRBool addServiceLocator,
CERTCertificate *signerCert); CERTCertificate *signerCert);
/* /*
* FUNCTION: CERT_AddOCSPAcceptableResponses * FUNCTION: CERT_AddOCSPAcceptableResponses
@ -243,13 +241,13 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
*/ */
extern SECStatus extern SECStatus
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request, CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
SECOidTag responseType0, ...); SECOidTag responseType0, ...);
/* /*
* FUNCTION: CERT_EncodeOCSPRequest * FUNCTION: CERT_EncodeOCSPRequest
* DER encodes an OCSP Request, possibly adding a signature as well. * DER encodes an OCSP Request, possibly adding a signature as well.
* XXX Signing is not yet supported, however; see comments in code. * XXX Signing is not yet supported, however; see comments in code.
* INPUTS: * INPUTS:
* PLArenaPool *arena * PLArenaPool *arena
* The return value is allocated from here. * The return value is allocated from here.
* If a NULL is passed in, allocation is done from the heap instead. * If a NULL is passed in, allocation is done from the heap instead.
@ -264,8 +262,8 @@ CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
* (e.g. no memory). * (e.g. no memory).
*/ */
extern SECItem * extern SECItem *
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request, CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
void *pwArg); void *pwArg);
/* /*
* FUNCTION: CERT_DecodeOCSPRequest * FUNCTION: CERT_DecodeOCSPRequest
@ -341,7 +339,7 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
* const char *location * const char *location
* The location of the OCSP responder (a URL). * The location of the OCSP responder (a URL).
* PRTime time * PRTime time
* Indicates the time for which the certificate status is to be * Indicates the time for which the certificate status is to be
* determined -- this may be used in the search for the cert's issuer * determined -- this may be used in the search for the cert's issuer
* but has no other bearing on the operation. * but has no other bearing on the operation.
* PRBool addServiceLocator * PRBool addServiceLocator
@ -369,10 +367,10 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
*/ */
extern SECItem * extern SECItem *
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList, CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
const char *location, PRTime time, const char *location, PRTime time,
PRBool addServiceLocator, PRBool addServiceLocator,
CERTCertificate *signerCert, void *pwArg, CERTCertificate *signerCert, void *pwArg,
CERTOCSPRequest **pRequest); CERTOCSPRequest **pRequest);
/* /*
* FUNCTION: CERT_VerifyOCSPResponseSignature * FUNCTION: CERT_VerifyOCSPResponseSignature
@ -406,10 +404,10 @@ CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
* verifying the signer's cert, or low-level problems (no memory, etc.) * verifying the signer's cert, or low-level problems (no memory, etc.)
*/ */
extern SECStatus extern SECStatus
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response, CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
CERTCertDBHandle *handle, void *pwArg, CERTCertDBHandle *handle, void *pwArg,
CERTCertificate **pSignerCert, CERTCertificate **pSignerCert,
CERTCertificate *issuerCert); CERTCertificate *issuerCert);
/* /*
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
@ -425,7 +423,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
* extension is not present or it does not contain an entry for OCSP, * extension is not present or it does not contain an entry for OCSP,
* SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned. * SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned.
* Any other error will also result in a NULL being returned. * Any other error will also result in a NULL being returned.
* *
* This result should be freed (via PORT_Free) when no longer in use. * This result should be freed (via PORT_Free) when no longer in use.
*/ */
extern char * extern char *
@ -433,21 +431,21 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert);
/* /*
* FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack * FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack
* This function serves two purposes. * This function serves two purposes.
* 1) It registers the address of a callback function that will be * 1) It registers the address of a callback function that will be
* called for certs that have no OCSP AIA extension, to see if the * called for certs that have no OCSP AIA extension, to see if the
* callback wishes to supply an alternative URL for such an OCSP inquiry. * callback wishes to supply an alternative URL for such an OCSP inquiry.
* 2) It outputs the previously registered function's address to the * 2) It outputs the previously registered function's address to the
* address supplied by the caller, unless that is NULL. * address supplied by the caller, unless that is NULL.
* The registered callback function returns NULL, or an allocated string * The registered callback function returns NULL, or an allocated string
* that may be subsequently freed by calling PORT_Free(). * that may be subsequently freed by calling PORT_Free().
* RETURN: * RETURN:
* SECSuccess or SECFailure (if the library is not yet intialized) * SECSuccess or SECFailure (if the library is not yet intialized)
*/ */
extern SECStatus extern SECStatus
CERT_RegisterAlternateOCSPAIAInfoCallBack( CERT_RegisterAlternateOCSPAIAInfoCallBack(
CERT_StringFromCertFcn newCallback, CERT_StringFromCertFcn newCallback,
CERT_StringFromCertFcn * oldCallback); CERT_StringFromCertFcn *oldCallback);
/* /*
* FUNCTION: CERT_ParseURL * FUNCTION: CERT_ParseURL
@ -521,10 +519,10 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath);
* (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
* verifying the signer's cert, or low-level problems (error allocating * verifying the signer's cert, or low-level problems (error allocating
* memory, error performing ASN.1 decoding, etc.). * memory, error performing ASN.1 decoding, etc.).
*/ */
extern SECStatus extern SECStatus
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
PRTime time, void *pwArg); PRTime time, void *pwArg);
/* /*
* FUNCTION: CERT_CacheOCSPResponseFromSideChannel * FUNCTION: CERT_CacheOCSPResponseFromSideChannel
@ -556,10 +554,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
*/ */
extern SECStatus extern SECStatus
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle, CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
CERTCertificate *cert, CERTCertificate *cert,
PRTime time, PRTime time,
const SECItem *encodedResponse, const SECItem *encodedResponse,
void *pwArg); void *pwArg);
/* /*
* FUNCTION: CERT_GetOCSPStatusForCertID * FUNCTION: CERT_GetOCSPStatusForCertID
@ -581,11 +579,11 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
* Return values are the same as those for CERT_CheckOCSPStatus * Return values are the same as those for CERT_CheckOCSPStatus
*/ */
extern SECStatus extern SECStatus
CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle, CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
CERTOCSPResponse *response, CERTOCSPResponse *response,
CERTOCSPCertID *certID, CERTOCSPCertID *certID,
CERTCertificate *signerCert, CERTCertificate *signerCert,
PRTime time); PRTime time);
/* /*
* FUNCTION CERT_GetOCSPResponseStatus * FUNCTION CERT_GetOCSPResponseStatus
@ -619,10 +617,10 @@ CERT_GetOCSPResponseStatus(CERTOCSPResponse *response);
* the issuing CA may be an older expired certificate. * the issuing CA may be an older expired certificate.
* RETURN: * RETURN:
* A new copy of a CERTOCSPCertID*. The memory for this certID * A new copy of a CERTOCSPCertID*. The memory for this certID
* should be freed by calling CERT_DestroyOCSPCertID when the * should be freed by calling CERT_DestroyOCSPCertID when the
* certID is no longer necessary. * certID is no longer necessary.
*/ */
extern CERTOCSPCertID* extern CERTOCSPCertID *
CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time); CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
/* /*
@ -630,7 +628,7 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
* Frees the memory associated with the certID passed in. * Frees the memory associated with the certID passed in.
* INPUTS: * INPUTS:
* CERTOCSPCertID* certID * CERTOCSPCertID* certID
* The certID that the caller no longer needs and wants to * The certID that the caller no longer needs and wants to
* free the associated memory. * free the associated memory.
* RETURN: * RETURN:
* SECSuccess if freeing the memory was successful. Returns * SECSuccess if freeing the memory was successful. Returns
@ -638,31 +636,30 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
* a call to CERT_CreateOCSPCertID. * a call to CERT_CreateOCSPCertID.
*/ */
extern SECStatus extern SECStatus
CERT_DestroyOCSPCertID(CERTOCSPCertID* certID); CERT_DestroyOCSPCertID(CERTOCSPCertID *certID);
extern CERTOCSPSingleResponse *
extern CERTOCSPSingleResponse*
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena, CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
CERTOCSPCertID *id, CERTOCSPCertID *id,
PRTime thisUpdate, PRTime thisUpdate,
const PRTime *nextUpdate); const PRTime *nextUpdate);
extern CERTOCSPSingleResponse* extern CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena, CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
CERTOCSPCertID *id, CERTOCSPCertID *id,
PRTime thisUpdate, PRTime thisUpdate,
const PRTime *nextUpdate); const PRTime *nextUpdate);
extern CERTOCSPSingleResponse* extern CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseRevoked( CERT_CreateOCSPSingleResponseRevoked(
PLArenaPool *arena, PLArenaPool *arena,
CERTOCSPCertID *id, CERTOCSPCertID *id,
PRTime thisUpdate, PRTime thisUpdate,
const PRTime *nextUpdate, const PRTime *nextUpdate,
PRTime revocationTime, PRTime revocationTime,
const CERTCRLEntryReasonCode* revocationReason); const CERTCRLEntryReasonCode *revocationReason);
extern SECItem* extern SECItem *
CERT_CreateEncodedOCSPSuccessResponse( CERT_CreateEncodedOCSPSuccessResponse(
PLArenaPool *arena, PLArenaPool *arena,
CERTCertificate *responderCert, CERTCertificate *responderCert,
@ -703,7 +700,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
* SEC_ERROR_INVALID_ARGS * SEC_ERROR_INVALID_ARGS
* Other errors are low-level problems (no memory, bad database, etc.). * Other errors are low-level problems (no memory, bad database, etc.).
*/ */
extern SECItem* extern SECItem *
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error); CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
/* Sends an OCSP request using the HTTP POST method to the location addressed /* Sends an OCSP request using the HTTP POST method to the location addressed
@ -717,7 +714,7 @@ CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
* SEC_RegisterDefaultHttpClient then that client is used. Otherwise, an * SEC_RegisterDefaultHttpClient then that client is used. Otherwise, an
* internal HTTP client is used. * internal HTTP client is used.
*/ */
SECItem* CERT_PostOCSPRequest(PLArenaPool *arena, const char *location, SECItem *CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest); const SECItem *encodedRequest);
/************************************************************************/ /************************************************************************/

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

@ -35,13 +35,15 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
void *pwArg); void *pwArg);
CERTOCSPRequest * CERTOCSPRequest *
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID, cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
CERTCertificate *singleCert, CERTCertificate *singleCert,
PRTime time, PRTime time,
PRBool addServiceLocator, PRBool addServiceLocator,
CERTCertificate *signerCert); CERTCertificate *signerCert);
typedef enum { ocspMissing, ocspFresh, ocspStale } OCSPFreshness; typedef enum { ocspMissing,
ocspFresh,
ocspStale } OCSPFreshness;
SECStatus SECStatus
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID, ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
@ -84,13 +86,13 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
*/ */
SECStatus SECStatus
cert_ProcessOCSPResponse(CERTCertDBHandle *handle, cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
CERTOCSPResponse *response, CERTOCSPResponse *response,
CERTOCSPCertID *certID, CERTOCSPCertID *certID,
CERTCertificate *signerCert, CERTCertificate *signerCert,
PRTime time, PRTime time,
PRBool *certIDWasConsumed, PRBool *certIDWasConsumed,
SECStatus *cacheUpdateStatus); SECStatus *cacheUpdateStatus);
/* /*
* FUNCTION: cert_RememberOCSPProcessingFailure * FUNCTION: cert_RememberOCSPProcessingFailure
@ -109,7 +111,7 @@ cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
SECStatus SECStatus
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID, cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
PRBool *certIDWasConsumed); PRBool *certIDWasConsumed);
/* /*
* FUNCTION: ocsp_GetResponderLocation * FUNCTION: ocsp_GetResponderLocation
@ -146,11 +148,11 @@ size_t
ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf); ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf);
SECStatus SECStatus
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
CERTOCSPResponse *response, CERTOCSPResponse *response,
CERTOCSPCertID *certID, CERTOCSPCertID *certID,
CERTCertificate *signerCert, CERTCertificate *signerCert,
PRTime time, PRTime time,
CERTOCSPSingleResponse **pSingleResponse); CERTOCSPSingleResponse **pSingleResponse);
SECStatus SECStatus
@ -158,7 +160,7 @@ ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time);
void void
ocsp_CacheSingleResponse(CERTOCSPCertID *certID, ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
CERTOCSPSingleResponse *single, CERTOCSPSingleResponse *single,
PRBool *certIDWasConsumed); PRBool *certIDWasConsumed);
#endif /* _OCSPI_H_ */ #endif /* _OCSPI_H_ */

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

@ -19,12 +19,11 @@
#include "ocspi.h" #include "ocspi.h"
#include "pk11pub.h" #include "pk11pub.h"
extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[]; extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[]; extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[]; extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];
ocspCertStatus* ocspCertStatus *
ocsp_CreateCertStatus(PLArenaPool *arena, ocsp_CreateCertStatus(PLArenaPool *arena,
ocspCertStatusType status, ocspCertStatusType status,
PRTime revocationTime) PRTime revocationTime)
@ -45,7 +44,7 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
} }
cs = PORT_ArenaZNew(arena, ocspCertStatus); cs = PORT_ArenaZNew(arena, ocspCertStatus);
if (!cs) if (!cs)
return NULL; return NULL;
@ -71,8 +70,9 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
if (!cs->certStatusInfo.revokedInfo->revocationReason) if (!cs->certStatusInfo.revokedInfo->revocationReason)
return NULL; return NULL;
if (DER_TimeToGeneralizedTimeArena(arena, if (DER_TimeToGeneralizedTimeArena(arena,
&cs->certStatusInfo.revokedInfo->revocationTime, &cs->certStatusInfo.revokedInfo->revocationTime,
revocationTime) != SECSuccess) revocationTime) !=
SECSuccess)
return NULL; return NULL;
break; break;
default: default:
@ -91,11 +91,11 @@ static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = { static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
{ SEC_ASN1_GENERALIZED_TIME, { SEC_ASN1_GENERALIZED_TIME,
offsetof(ocspRevokedInfo, revocationTime) }, offsetof(ocspRevokedInfo, revocationTime) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0, SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(ocspRevokedInfo, revocationReason), offsetof(ocspRevokedInfo, revocationReason),
mySEC_PointerToEnumeratedTemplate }, mySEC_PointerToEnumeratedTemplate },
{ 0 } { 0 }
}; };
@ -110,26 +110,26 @@ static const SEC_ASN1Template mySEC_NullTemplate[] = {
static const SEC_ASN1Template ocsp_CertStatusTemplate[] = { static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
{ SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType), { SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
0, sizeof(ocspCertStatus) }, 0, sizeof(ocspCertStatus) },
{ SEC_ASN1_CONTEXT_SPECIFIC | 0, { SEC_ASN1_CONTEXT_SPECIFIC | 0,
0, mySEC_NullTemplate, ocspCertStatus_good }, 0, mySEC_NullTemplate, ocspCertStatus_good },
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_CONTEXT_SPECIFIC | 1, SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(ocspCertStatus, certStatusInfo.revokedInfo), offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked }, ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
{ SEC_ASN1_CONTEXT_SPECIFIC | 2, { SEC_ASN1_CONTEXT_SPECIFIC | 2,
0, mySEC_NullTemplate, ocspCertStatus_unknown }, 0, mySEC_NullTemplate, ocspCertStatus_unknown },
{ 0 } { 0 }
}; };
static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = { static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SECAlgorithmID) }, 0, NULL, sizeof(SECAlgorithmID) },
{ SEC_ASN1_OBJECT_ID, { SEC_ASN1_OBJECT_ID,
offsetof(SECAlgorithmID,algorithm), }, offsetof(SECAlgorithmID, algorithm) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
offsetof(SECAlgorithmID,parameters), }, offsetof(SECAlgorithmID, parameters) },
{ 0, } { 0 }
}; };
static const SEC_ASN1Template mySEC_AnyTemplate[] = { static const SEC_ASN1Template mySEC_AnyTemplate[] = {
@ -153,7 +153,7 @@ static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
}; };
static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = { static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
{ SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)} { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
}; };
static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = { static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
@ -162,29 +162,29 @@ static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
static const SEC_ASN1Template ocsp_myCertIDTemplate[] = { static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTOCSPCertID) }, 0, NULL, sizeof(CERTOCSPCertID) },
{ SEC_ASN1_INLINE, { SEC_ASN1_INLINE,
offsetof(CERTOCSPCertID, hashAlgorithm), offsetof(CERTOCSPCertID, hashAlgorithm),
mySECOID_AlgorithmIDTemplate }, mySECOID_AlgorithmIDTemplate },
{ SEC_ASN1_OCTET_STRING, { SEC_ASN1_OCTET_STRING,
offsetof(CERTOCSPCertID, issuerNameHash) }, offsetof(CERTOCSPCertID, issuerNameHash) },
{ SEC_ASN1_OCTET_STRING, { SEC_ASN1_OCTET_STRING,
offsetof(CERTOCSPCertID, issuerKeyHash) }, offsetof(CERTOCSPCertID, issuerKeyHash) },
{ SEC_ASN1_INTEGER, { SEC_ASN1_INTEGER,
offsetof(CERTOCSPCertID, serialNumber) }, offsetof(CERTOCSPCertID, serialNumber) },
{ 0 } { 0 }
}; };
static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = { static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTCertExtension) }, 0, NULL, sizeof(CERTCertExtension) },
{ SEC_ASN1_OBJECT_ID, { SEC_ASN1_OBJECT_ID,
offsetof(CERTCertExtension,id) }, offsetof(CERTCertExtension, id) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
offsetof(CERTCertExtension,critical) }, offsetof(CERTCertExtension, critical) },
{ SEC_ASN1_OCTET_STRING, { SEC_ASN1_OCTET_STRING,
offsetof(CERTCertExtension,value) }, offsetof(CERTCertExtension, value) },
{ 0, } { 0 }
}; };
static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = { static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
@ -197,66 +197,65 @@ static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[]
static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = { static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTOCSPSingleResponse) }, 0, NULL, sizeof(CERTOCSPSingleResponse) },
{ SEC_ASN1_POINTER, { SEC_ASN1_POINTER,
offsetof(CERTOCSPSingleResponse, certID), offsetof(CERTOCSPSingleResponse, certID),
ocsp_myCertIDTemplate }, ocsp_myCertIDTemplate },
{ SEC_ASN1_ANY, { SEC_ASN1_ANY,
offsetof(CERTOCSPSingleResponse, derCertStatus) }, offsetof(CERTOCSPSingleResponse, derCertStatus) },
{ SEC_ASN1_GENERALIZED_TIME, { SEC_ASN1_GENERALIZED_TIME,
offsetof(CERTOCSPSingleResponse, thisUpdate) }, offsetof(CERTOCSPSingleResponse, thisUpdate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(CERTOCSPSingleResponse, nextUpdate), offsetof(CERTOCSPSingleResponse, nextUpdate),
mySEC_PointerToGeneralizedTimeTemplate }, mySEC_PointerToGeneralizedTimeTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(CERTOCSPSingleResponse, singleExtensions), offsetof(CERTOCSPSingleResponse, singleExtensions),
myCERT_PointerToSequenceOfCertExtensionTemplate }, myCERT_PointerToSequenceOfCertExtensionTemplate },
{ 0 } { 0 }
}; };
static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = { static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(ocspResponseData) }, 0, NULL, sizeof(ocspResponseData) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */ { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(ocspResponseData, version), offsetof(ocspResponseData, version),
mySEC_PointerToIntegerTemplate }, mySEC_PointerToIntegerTemplate },
{ SEC_ASN1_ANY, { SEC_ASN1_ANY,
offsetof(ocspResponseData, derResponderID) }, offsetof(ocspResponseData, derResponderID) },
{ SEC_ASN1_GENERALIZED_TIME, { SEC_ASN1_GENERALIZED_TIME,
offsetof(ocspResponseData, producedAt) }, offsetof(ocspResponseData, producedAt) },
{ SEC_ASN1_SEQUENCE_OF, { SEC_ASN1_SEQUENCE_OF,
offsetof(ocspResponseData, responses), offsetof(ocspResponseData, responses),
ocsp_mySingleResponseTemplate }, ocsp_mySingleResponseTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(ocspResponseData, responseExtensions), offsetof(ocspResponseData, responseExtensions),
myCERT_PointerToSequenceOfCertExtensionTemplate }, myCERT_PointerToSequenceOfCertExtensionTemplate },
{ 0 } { 0 }
}; };
static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = { static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(ocspBasicOCSPResponse) }, 0, NULL, sizeof(ocspBasicOCSPResponse) },
{ SEC_ASN1_POINTER, { SEC_ASN1_POINTER,
offsetof(ocspBasicOCSPResponse, tbsResponseData), offsetof(ocspBasicOCSPResponse, tbsResponseData),
ocsp_myResponseDataTemplate }, ocsp_myResponseDataTemplate },
{ SEC_ASN1_INLINE, { SEC_ASN1_INLINE,
offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm), offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
mySECOID_AlgorithmIDTemplate }, mySECOID_AlgorithmIDTemplate },
{ SEC_ASN1_BIT_STRING, { SEC_ASN1_BIT_STRING,
offsetof(ocspBasicOCSPResponse, responseSignature.signature) }, offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(ocspBasicOCSPResponse, responseSignature.derCerts), offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
mySEC_PointerToSequenceOfAnyTemplate }, mySEC_PointerToSequenceOfAnyTemplate },
{ 0 } { 0 }
}; };
static CERTOCSPSingleResponse* static CERTOCSPSingleResponse *
ocsp_CreateSingleResponse(PLArenaPool *arena, ocsp_CreateSingleResponse(PLArenaPool *arena,
CERTOCSPCertID *id, ocspCertStatus *status, CERTOCSPCertID *id, ocspCertStatus *status,
PRTime thisUpdate, const PRTime *nextUpdate) PRTime thisUpdate, const PRTime *nextUpdate)
@ -274,25 +273,25 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
sr->arena = arena; sr->arena = arena;
sr->certID = id; sr->certID = id;
sr->certStatus = status; sr->certStatus = status;
if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) !=
!= SECSuccess) SECSuccess)
return NULL; return NULL;
sr->nextUpdate = NULL; sr->nextUpdate = NULL;
if (nextUpdate) { if (nextUpdate) {
sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0); sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
if (!sr->nextUpdate) if (!sr->nextUpdate)
return NULL; return NULL;
if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) !=
!= SECSuccess) SECSuccess)
return NULL; return NULL;
} }
sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1); sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension *, 1);
if (!sr->singleExtensions) if (!sr->singleExtensions)
return NULL; return NULL;
sr->singleExtensions[0] = NULL; sr->singleExtensions[0] = NULL;
if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus, if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
status, ocsp_CertStatusTemplate)) status, ocsp_CertStatusTemplate))
return NULL; return NULL;
@ -300,13 +299,13 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
return sr; return sr;
} }
CERTOCSPSingleResponse* CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena, CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
CERTOCSPCertID *id, CERTOCSPCertID *id,
PRTime thisUpdate, PRTime thisUpdate,
const PRTime *nextUpdate) const PRTime *nextUpdate)
{ {
ocspCertStatus * cs; ocspCertStatus *cs;
if (!arena) { if (!arena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
@ -317,13 +316,13 @@ CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
} }
CERTOCSPSingleResponse* CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena, CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
CERTOCSPCertID *id, CERTOCSPCertID *id,
PRTime thisUpdate, PRTime thisUpdate,
const PRTime *nextUpdate) const PRTime *nextUpdate)
{ {
ocspCertStatus * cs; ocspCertStatus *cs;
if (!arena) { if (!arena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
@ -334,16 +333,16 @@ CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
} }
CERTOCSPSingleResponse* CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseRevoked( CERT_CreateOCSPSingleResponseRevoked(
PLArenaPool *arena, PLArenaPool *arena,
CERTOCSPCertID *id, CERTOCSPCertID *id,
PRTime thisUpdate, PRTime thisUpdate,
const PRTime *nextUpdate, const PRTime *nextUpdate,
PRTime revocationTime, PRTime revocationTime,
const CERTCRLEntryReasonCode* revocationReason) const CERTCRLEntryReasonCode *revocationReason)
{ {
ocspCertStatus * cs; ocspCertStatus *cs;
/* revocationReason is not yet supported, so it must be NULL. */ /* revocationReason is not yet supported, so it must be NULL. */
if (!arena || revocationReason) { if (!arena || revocationReason) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -357,7 +356,7 @@ CERT_CreateOCSPSingleResponseRevoked(
/* responderCert == 0 means: /* responderCert == 0 means:
* create a response with an invalid signature (for testing purposes) */ * create a response with an invalid signature (for testing purposes) */
SECItem* SECItem *
CERT_CreateEncodedOCSPSuccessResponse( CERT_CreateEncodedOCSPSuccessResponse(
PLArenaPool *arena, PLArenaPool *arena,
CERTCertificate *responderCert, CERTCertificate *responderCert,
@ -373,12 +372,12 @@ CERT_CreateEncodedOCSPSuccessResponse(
ocspBasicOCSPResponse *br = NULL; ocspBasicOCSPResponse *br = NULL;
ocspResponseBytes *rb = NULL; ocspResponseBytes *rb = NULL;
CERTOCSPResponse *response = NULL; CERTOCSPResponse *response = NULL;
SECOidTag algID; SECOidTag algID;
SECOidData *od = NULL; SECOidData *od = NULL;
SECKEYPrivateKey *privKey = NULL; SECKEYPrivateKey *privKey = NULL;
SECItem *result = NULL; SECItem *result = NULL;
if (!arena || !responses) { if (!arena || !responses) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
@ -408,114 +407,114 @@ CERT_CreateEncodedOCSPSuccessResponse(
response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse); response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
if (!response) if (!response)
goto done; goto done;
rd->version.data=NULL; rd->version.data = NULL;
rd->version.len=0; rd->version.len = 0;
rd->responseExtensions = NULL; rd->responseExtensions = NULL;
rd->responses = responses; rd->responses = responses;
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) !=
!= SECSuccess) SECSuccess)
goto done; goto done;
if (!responderCert) { if (!responderCert) {
/* use invalid signature for testing purposes */ /* use invalid signature for testing purposes */
unsigned char dummyChar = 'd'; unsigned char dummyChar = 'd';
SECItem dummy; SECItem dummy;
dummy.len = 1; dummy.len = 1;
dummy.data = &dummyChar; dummy.data = &dummyChar;
/* it's easier to produdce a keyHash out of nowhere, /* it's easier to produdce a keyHash out of nowhere,
* than to produce an encoded subject, * than to produce an encoded subject,
* so for our dummy response we always use byKey * so for our dummy response we always use byKey
*/ */
rid->responderIDType = ocspResponderID_byKey;
if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
&dummy))
goto done;
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, rid->responderIDType = ocspResponderID_byKey;
ocsp_ResponderIDByKeyTemplate)) if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
goto done; &dummy))
goto done;
br->tbsResponseData = rd; if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
ocsp_ResponderIDByKeyTemplate))
goto done;
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData, br->tbsResponseData = rd;
ocsp_myResponseDataTemplate))
goto done;
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1); if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
if (!br->responseSignature.derCerts) ocsp_myResponseDataTemplate))
goto done; goto done;
br->responseSignature.derCerts[0] = NULL;
algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1); br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
if (algID == SEC_OID_UNKNOWN) if (!br->responseSignature.derCerts)
goto done; goto done;
br->responseSignature.derCerts[0] = NULL;
/* match the regular signature code, which doesn't use the arena */ algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1)) if (algID == SEC_OID_UNKNOWN)
goto done; goto done;
PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
/* convert len-in-bytes to len-in-bits */ /* match the regular signature code, which doesn't use the arena */
br->responseSignature.signature.len = br->responseSignature.signature.len << 3; if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
goto done;
PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
/* convert len-in-bytes to len-in-bits */
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
} }
else { else {
rid->responderIDType = responderIDType; rid->responderIDType = responderIDType;
if (responderIDType == ocspResponderID_byName) { if (responderIDType == ocspResponderID_byName) {
responderIDTemplate = ocsp_ResponderIDByNameTemplate; responderIDTemplate = ocsp_ResponderIDByNameTemplate;
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name, if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
&responderCert->subject) != SECSuccess) &responderCert->subject) != SECSuccess)
goto done; goto done;
} }
else { else {
responderIDTemplate = ocsp_ResponderIDByKeyTemplate; responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert, if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
SEC_OID_SHA1, &rid->responderIDValue.keyHash)) SEC_OID_SHA1, &rid->responderIDValue.keyHash))
goto done; goto done;
} }
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
responderIDTemplate)) responderIDTemplate))
goto done; goto done;
br->tbsResponseData = rd; br->tbsResponseData = rd;
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData, if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
ocsp_myResponseDataTemplate)) ocsp_myResponseDataTemplate))
goto done; goto done;
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1); br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
if (!br->responseSignature.derCerts) if (!br->responseSignature.derCerts)
goto done; goto done;
br->responseSignature.derCerts[0] = NULL; br->responseSignature.derCerts[0] = NULL;
privKey = PK11_FindKeyByAnyCert(responderCert, wincx); privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
if (!privKey) if (!privKey)
goto done; goto done;
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1); algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
if (algID == SEC_OID_UNKNOWN) if (algID == SEC_OID_UNKNOWN)
goto done; goto done;
if (SEC_SignData(&br->responseSignature.signature, if (SEC_SignData(&br->responseSignature.signature,
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len, br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
privKey, algID) privKey, algID) !=
!= SECSuccess) SECSuccess)
goto done; goto done;
/* convert len-in-bytes to len-in-bits */ /* convert len-in-bytes to len-in-bits */
br->responseSignature.signature.len = br->responseSignature.signature.len << 3; br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
/* br->responseSignature.signature wasn't allocated from arena, /* br->responseSignature.signature wasn't allocated from arena,
* we must free it when done. */ * we must free it when done. */
} }
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) !=
!= SECSuccess) SECSuccess)
goto done; goto done;
if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br, if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
ocsp_EncodeBasicOCSPResponseTemplate)) ocsp_EncodeBasicOCSPResponseTemplate))
@ -552,15 +551,15 @@ done:
static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = { static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE, { SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTOCSPResponse) }, 0, NULL, sizeof(CERTOCSPResponse) },
{ SEC_ASN1_ENUMERATED, { SEC_ASN1_ENUMERATED,
offsetof(CERTOCSPResponse, responseStatus) }, offsetof(CERTOCSPResponse, responseStatus) },
{ 0, 0, { 0, 0,
mySEC_NullTemplate }, mySEC_NullTemplate },
{ 0 } { 0 }
}; };
SECItem* SECItem *
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error) CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
{ {
CERTOCSPResponse response; CERTOCSPResponse response;

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

@ -46,8 +46,8 @@ typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse;
* dependent, and should be opaque to the user. * dependent, and should be opaque to the user.
*/ */
typedef void * SEC_HTTP_SERVER_SESSION; typedef void *SEC_HTTP_SERVER_SESSION;
typedef void * SEC_HTTP_REQUEST_SESSION; typedef void *SEC_HTTP_REQUEST_SESSION;
/* /*
* This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a * This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a
@ -61,9 +61,9 @@ typedef void * SEC_HTTP_REQUEST_SESSION;
* after processing is finished. * after processing is finished.
*/ */
typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)( typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
const char *host, const char *host,
PRUint16 portnum, PRUint16 portnum,
SEC_HTTP_SERVER_SESSION *pSession); SEC_HTTP_SERVER_SESSION *pSession);
/* /*
* This function is called to allow the implementation to attempt to keep * This function is called to allow the implementation to attempt to keep
@ -77,10 +77,10 @@ typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
* SECWouldBlock and store a nonzero value at "pPollDesc". In that case * SECWouldBlock and store a nonzero value at "pPollDesc". In that case
* the caller may wait on the poll descriptor, and should call this function * the caller may wait on the poll descriptor, and should call this function
* again until SECSuccess (and a zero value at "pPollDesc") is obtained. * again until SECSuccess (and a zero value at "pPollDesc") is obtained.
*/ */
typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)( typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
SEC_HTTP_SERVER_SESSION session, SEC_HTTP_SERVER_SESSION session,
PRPollDesc **pPollDesc); PRPollDesc **pPollDesc);
/* /*
* This function frees the client SEC_HTTP_SERVER_SESSION object, closes all * This function frees the client SEC_HTTP_SERVER_SESSION object, closes all
@ -88,9 +88,9 @@ typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
* frees any memory that was allocated by the client, and invalidates any * frees any memory that was allocated by the client, and invalidates any
* response pointers that might have been returned by prior server or request * response pointers that might have been returned by prior server or request
* functions. * functions.
*/ */
typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)( typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
SEC_HTTP_SERVER_SESSION session); SEC_HTTP_SERVER_SESSION session);
/* /*
* This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a * This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a
@ -111,30 +111,30 @@ typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
* after processing is finished. * after processing is finished.
*/ */
typedef SECStatus (*SEC_HttpRequest_CreateFcn)( typedef SECStatus (*SEC_HttpRequest_CreateFcn)(
SEC_HTTP_SERVER_SESSION session, SEC_HTTP_SERVER_SESSION session,
const char *http_protocol_variant, /* usually "http" */ const char *http_protocol_variant, /* usually "http" */
const char *path_and_query_string, const char *path_and_query_string,
const char *http_request_method, const char *http_request_method,
const PRIntervalTime timeout, const PRIntervalTime timeout,
SEC_HTTP_REQUEST_SESSION *pRequest); SEC_HTTP_REQUEST_SESSION *pRequest);
/* /*
* This function sets data to be sent to the server for an HTTP request * This function sets data to be sent to the server for an HTTP request
* of http_request_method == POST. If a particular implementation * of http_request_method == POST. If a particular implementation
* supports it, the details for the POST request can be set by calling * supports it, the details for the POST request can be set by calling
* this function, prior to activating the request with TrySendAndReceiveFcn. * this function, prior to activating the request with TrySendAndReceiveFcn.
* *
* An implementation that does not support the POST method should * An implementation that does not support the POST method should
* implement a SetPostDataFcn function that returns immediately. * implement a SetPostDataFcn function that returns immediately.
* *
* Setting http_content_type is optional, the parameter may * Setting http_content_type is optional, the parameter may
* by NULL or the empty string. * by NULL or the empty string.
*/ */
typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)( typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
SEC_HTTP_REQUEST_SESSION request, SEC_HTTP_REQUEST_SESSION request,
const char *http_data, const char *http_data,
const PRUint32 http_data_len, const PRUint32 http_data_len,
const char *http_content_type); const char *http_content_type);
/* /*
* This function sets an additional HTTP protocol request header. * This function sets an additional HTTP protocol request header.
@ -144,11 +144,11 @@ typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
* *
* An implementation that does not support setting additional headers * An implementation that does not support setting additional headers
* should implement an AddRequestHeaderFcn function that returns immediately. * should implement an AddRequestHeaderFcn function that returns immediately.
*/ */
typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)( typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
SEC_HTTP_REQUEST_SESSION request, SEC_HTTP_REQUEST_SESSION request,
const char *http_header_name, const char *http_header_name,
const char *http_header_value); const char *http_header_value);
/* /*
* This function initiates or continues an HTTP request. After * This function initiates or continues an HTTP request. After
@ -180,10 +180,10 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
* size, the function will return SECFailure. * size, the function will return SECFailure.
* http_response_data_len will be set to a value different from zero to * http_response_data_len will be set to a value different from zero to
* indicate the reason of the failure. * indicate the reason of the failure.
* An out value of "0" means, the failure was unrelated to the * An out value of "0" means, the failure was unrelated to the
* acceptable size. * acceptable size.
* An out value of "1" means, the result data is larger than the * An out value of "1" means, the result data is larger than the
* accpeptable size, but the real size is not yet known to the http client * accpeptable size, but the real size is not yet known to the http client
* implementation and it stopped retrieving it, * implementation and it stopped retrieving it,
* Any other out value combined with a return value of SECFailure * Any other out value combined with a return value of SECFailure
* will indicate the actual size of the server data. * will indicate the actual size of the server data.
@ -195,64 +195,64 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
* the completion of the operation. * the completion of the operation.
* *
* All returned pointers will be owned by the the HttpClient * All returned pointers will be owned by the the HttpClient
* implementation and will remain valid until the call to * implementation and will remain valid until the call to
* SEC_HttpRequest_FreeFcn. * SEC_HttpRequest_FreeFcn.
*/ */
typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)( typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)(
SEC_HTTP_REQUEST_SESSION request, SEC_HTTP_REQUEST_SESSION request,
PRPollDesc **pPollDesc, PRPollDesc **pPollDesc,
PRUint16 *http_response_code, PRUint16 *http_response_code,
const char **http_response_content_type, const char **http_response_content_type,
const char **http_response_headers, const char **http_response_headers,
const char **http_response_data, const char **http_response_data,
PRUint32 *http_response_data_len); PRUint32 *http_response_data_len);
/* /*
* Calling CancelFcn asks for premature termination of the request. * Calling CancelFcn asks for premature termination of the request.
* *
* Future calls to SEC_HttpRequest_TrySendAndReceive should * Future calls to SEC_HttpRequest_TrySendAndReceive should
* by avoided, but in this case the HttpClient implementation * by avoided, but in this case the HttpClient implementation
* is expected to return immediately with SECFailure. * is expected to return immediately with SECFailure.
* *
* After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn * After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn
* is still necessary to free resources. * is still necessary to free resources.
*/ */
typedef SECStatus (*SEC_HttpRequest_CancelFcn)( typedef SECStatus (*SEC_HttpRequest_CancelFcn)(
SEC_HTTP_REQUEST_SESSION request); SEC_HTTP_REQUEST_SESSION request);
/* /*
* Before calling this function, it must be assured the request * Before calling this function, it must be assured the request
* has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has * has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has
* returned SECSuccess, or the request has been canceled with * returned SECSuccess, or the request has been canceled with
* a call to SEC_HttpRequest_CancelFcn. * a call to SEC_HttpRequest_CancelFcn.
* *
* This function frees the client state object, closes all sockets, * This function frees the client state object, closes all sockets,
* discards all partial results, frees any memory that was allocated * discards all partial results, frees any memory that was allocated
* by the client, and invalidates all response pointers that might * by the client, and invalidates all response pointers that might
* have been returned by SEC_HttpRequest_TrySendAndReceiveFcn * have been returned by SEC_HttpRequest_TrySendAndReceiveFcn
*/ */
typedef SECStatus (*SEC_HttpRequest_FreeFcn)( typedef SECStatus (*SEC_HttpRequest_FreeFcn)(
SEC_HTTP_REQUEST_SESSION request); SEC_HTTP_REQUEST_SESSION request);
typedef struct SEC_HttpClientFcnV1Struct { typedef struct SEC_HttpClientFcnV1Struct {
SEC_HttpServer_CreateSessionFcn createSessionFcn; SEC_HttpServer_CreateSessionFcn createSessionFcn;
SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn; SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn;
SEC_HttpServer_FreeSessionFcn freeSessionFcn; SEC_HttpServer_FreeSessionFcn freeSessionFcn;
SEC_HttpRequest_CreateFcn createFcn; SEC_HttpRequest_CreateFcn createFcn;
SEC_HttpRequest_SetPostDataFcn setPostDataFcn; SEC_HttpRequest_SetPostDataFcn setPostDataFcn;
SEC_HttpRequest_AddHeaderFcn addHeaderFcn; SEC_HttpRequest_AddHeaderFcn addHeaderFcn;
SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn; SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn;
SEC_HttpRequest_CancelFcn cancelFcn; SEC_HttpRequest_CancelFcn cancelFcn;
SEC_HttpRequest_FreeFcn freeFcn; SEC_HttpRequest_FreeFcn freeFcn;
} SEC_HttpClientFcnV1; } SEC_HttpClientFcnV1;
typedef struct SEC_HttpClientFcnStruct { typedef struct SEC_HttpClientFcnStruct {
PRInt16 version; PRInt16 version;
union { union {
SEC_HttpClientFcnV1 ftable1; SEC_HttpClientFcnV1 ftable1;
/* SEC_HttpClientFcnV2 ftable2; */ /* SEC_HttpClientFcnV2 ftable2; */
/* ... */ /* ... */
} fcnTable; } fcnTable;
} SEC_HttpClientFcn; } SEC_HttpClientFcn;
/* /*
@ -293,7 +293,7 @@ typedef enum {
*/ */
typedef enum { typedef enum {
ocspResponderID_other = -1, /* unknown kind of responderID */ ocspResponderID_other = -1, /* unknown kind of responderID */
ocspResponderID_byName = 1, ocspResponderID_byName = 1,
ocspResponderID_byKey = 2 ocspResponderID_byKey = 2
} CERTOCSPResponderIDType; } CERTOCSPResponderIDType;

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

@ -16,7 +16,6 @@
#include "seccomon.h" #include "seccomon.h"
#include "secoidt.h" #include "secoidt.h"
/* /*
* Some notes about naming conventions... * Some notes about naming conventions...
* *
@ -49,7 +48,6 @@
* way around (reference before definition). * way around (reference before definition).
*/ */
/* /*
* Forward-declarations of internal-only data structures. * Forward-declarations of internal-only data structures.
* *
@ -67,12 +65,11 @@ typedef struct ocspSingleRequestStr ocspSingleRequest;
typedef struct ocspSingleResponseStr ocspSingleResponse; typedef struct ocspSingleResponseStr ocspSingleResponse;
typedef struct ocspTBSRequestStr ocspTBSRequest; typedef struct ocspTBSRequestStr ocspTBSRequest;
/* /*
* An OCSPRequest; this is what is sent (encoded) to an OCSP responder. * An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
*/ */
struct CERTOCSPRequestStr { struct CERTOCSPRequestStr {
PLArenaPool *arena; /* local; not part of encoding */ PLArenaPool *arena; /* local; not part of encoding */
ocspTBSRequest *tbsRequest; ocspTBSRequest *tbsRequest;
ocspSignature *optionalSignature; ocspSignature *optionalSignature;
}; };
@ -92,12 +89,12 @@ struct CERTOCSPRequestStr {
* in-progress extensions as they are optionally added to the request. * in-progress extensions as they are optionally added to the request.
*/ */
struct ocspTBSRequestStr { struct ocspTBSRequestStr {
SECItem version; /* an INTEGER */ SECItem version; /* an INTEGER */
SECItem *derRequestorName; /* encoded GeneralName; see above */ SECItem *derRequestorName; /* encoded GeneralName; see above */
CERTGeneralNameList *requestorName; /* local; not part of encoding */ CERTGeneralNameList *requestorName; /* local; not part of encoding */
ocspSingleRequest **requestList; ocspSingleRequest **requestList;
CERTCertExtension **requestExtensions; CERTCertExtension **requestExtensions;
void *extensionHandle; /* local; not part of encoding */ void *extensionHandle; /* local; not part of encoding */
}; };
/* /*
@ -124,12 +121,12 @@ struct ocspTBSRequestStr {
*/ */
struct ocspSignatureStr { struct ocspSignatureStr {
SECAlgorithmID signatureAlgorithm; SECAlgorithmID signatureAlgorithm;
SECItem signature; /* a BIT STRING */ SECItem signature; /* a BIT STRING */
SECItem **derCerts; /* a SEQUENCE OF Certificate */ SECItem **derCerts; /* a SEQUENCE OF Certificate */
CERTCertificate *cert; /* local; not part of encoding */ CERTCertificate *cert; /* local; not part of encoding */
PRBool wasChecked; /* local; not part of encoding */ PRBool wasChecked; /* local; not part of encoding */
SECStatus status; /* local; not part of encoding */ SECStatus status; /* local; not part of encoding */
int failureReason; /* local; not part of encoding */ int failureReason; /* local; not part of encoding */
}; };
/* /*
@ -140,11 +137,11 @@ struct ocspSignatureStr {
* but since that seemed confusing (vs. an OCSPRequest) and to be more * but since that seemed confusing (vs. an OCSPRequest) and to be more
* consistent with the parallel type "SingleResponse", I called it a * consistent with the parallel type "SingleResponse", I called it a
* "SingleRequest". * "SingleRequest".
* *
* XXX figure out how to get rid of that arena -- there must be a way * XXX figure out how to get rid of that arena -- there must be a way
*/ */
struct ocspSingleRequestStr { struct ocspSingleRequestStr {
PLArenaPool *arena; /* just a copy of the response arena, PLArenaPool *arena; /* just a copy of the response arena,
* needed here for extension handling * needed here for extension handling
* routines, on creation only */ * routines, on creation only */
CERTOCSPCertID *reqCert; CERTOCSPCertID *reqCert;
@ -160,14 +157,14 @@ struct ocspSingleRequestStr {
*/ */
struct CERTOCSPCertIDStr { struct CERTOCSPCertIDStr {
SECAlgorithmID hashAlgorithm; SECAlgorithmID hashAlgorithm;
SECItem issuerNameHash; /* an OCTET STRING */ SECItem issuerNameHash; /* an OCTET STRING */
SECItem issuerKeyHash; /* an OCTET STRING */ SECItem issuerKeyHash; /* an OCTET STRING */
SECItem serialNumber; /* an INTEGER */ SECItem serialNumber; /* an INTEGER */
SECItem issuerSHA1NameHash; /* keep other hashes around when */ SECItem issuerSHA1NameHash; /* keep other hashes around when */
SECItem issuerMD5NameHash; /* we have them */ SECItem issuerMD5NameHash; /* we have them */
SECItem issuerMD2NameHash; SECItem issuerMD2NameHash;
SECItem issuerSHA1KeyHash; /* keep other hashes around when */ SECItem issuerSHA1KeyHash; /* keep other hashes around when */
SECItem issuerMD5KeyHash; /* we have them */ SECItem issuerMD5KeyHash; /* we have them */
SECItem issuerMD2KeyHash; SECItem issuerMD2KeyHash;
PLArenaPool *poolp; PLArenaPool *poolp;
}; };
@ -209,10 +206,10 @@ typedef enum {
* type ocspResponseStatus. * type ocspResponseStatus.
*/ */
struct CERTOCSPResponseStr { struct CERTOCSPResponseStr {
PLArenaPool *arena; /* local; not part of encoding */ PLArenaPool *arena; /* local; not part of encoding */
SECItem responseStatus; /* an ENUMERATED, see above */ SECItem responseStatus; /* an ENUMERATED, see above */
ocspResponseStatus statusValue; /* local; not part of encoding */ ocspResponseStatus statusValue; /* local; not part of encoding */
ocspResponseBytes *responseBytes; /* only when status is successful */ ocspResponseBytes *responseBytes; /* only when status is successful */
}; };
/* /*
@ -230,12 +227,12 @@ struct CERTOCSPResponseStr {
* response types, just add them to the union. * response types, just add them to the union.
*/ */
struct ocspResponseBytesStr { struct ocspResponseBytesStr {
SECItem responseType; /* an OBJECT IDENTIFIER */ SECItem responseType; /* an OBJECT IDENTIFIER */
SECOidTag responseTypeTag; /* local; not part of encoding */ SECOidTag responseTypeTag; /* local; not part of encoding */
SECItem response; /* an OCTET STRING */ SECItem response; /* an OCTET STRING */
union { union {
ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */ ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
} decodedResponse; /* local; not part of encoding */ } decodedResponse; /* local; not part of encoding */
}; };
/* /*
@ -250,7 +247,7 @@ struct ocspResponseBytesStr {
*/ */
struct ocspBasicOCSPResponseStr { struct ocspBasicOCSPResponseStr {
SECItem tbsResponseDataDER; SECItem tbsResponseDataDER;
ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */ ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
ocspSignature responseSignature; ocspSignature responseSignature;
}; };
@ -260,38 +257,38 @@ struct ocspBasicOCSPResponseStr {
* (a per-certificate status). * (a per-certificate status).
*/ */
struct ocspResponseDataStr { struct ocspResponseDataStr {
SECItem version; /* an INTEGER */ SECItem version; /* an INTEGER */
SECItem derResponderID; SECItem derResponderID;
ocspResponderID *responderID; /* local; not part of encoding */ ocspResponderID *responderID; /* local; not part of encoding */
SECItem producedAt; /* a GeneralizedTime */ SECItem producedAt; /* a GeneralizedTime */
CERTOCSPSingleResponse **responses; CERTOCSPSingleResponse **responses;
CERTCertExtension **responseExtensions; CERTCertExtension **responseExtensions;
}; };
struct ocspResponderIDStr { struct ocspResponderIDStr {
CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */ CERTOCSPResponderIDType responderIDType; /* local; not part of encoding */
union { union {
CERTName name; /* when ocspResponderID_byName */ CERTName name; /* when ocspResponderID_byName */
SECItem keyHash; /* when ocspResponderID_byKey */ SECItem keyHash; /* when ocspResponderID_byKey */
SECItem other; /* when ocspResponderID_other */ SECItem other; /* when ocspResponderID_other */
} responderIDValue; } responderIDValue;
}; };
/* /*
* The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
* SingleResponse -- one for each certificate whose status is being supplied. * SingleResponse -- one for each certificate whose status is being supplied.
* *
* XXX figure out how to get rid of that arena -- there must be a way * XXX figure out how to get rid of that arena -- there must be a way
*/ */
struct CERTOCSPSingleResponseStr { struct CERTOCSPSingleResponseStr {
PLArenaPool *arena; /* just a copy of the response arena, PLArenaPool *arena; /* just a copy of the response arena,
* needed here for extension handling * needed here for extension handling
* routines, on creation only */ * routines, on creation only */
CERTOCSPCertID *certID; CERTOCSPCertID *certID;
SECItem derCertStatus; SECItem derCertStatus;
ocspCertStatus *certStatus; /* local; not part of encoding */ ocspCertStatus *certStatus; /* local; not part of encoding */
SECItem thisUpdate; /* a GeneralizedTime */ SECItem thisUpdate; /* a GeneralizedTime */
SECItem *nextUpdate; /* a GeneralizedTime */ SECItem *nextUpdate; /* a GeneralizedTime */
CERTCertExtension **singleExtensions; CERTCertExtension **singleExtensions;
}; };
@ -313,10 +310,10 @@ struct CERTOCSPSingleResponseStr {
*/ */
typedef enum { typedef enum {
ocspCertStatus_good, /* cert is not revoked */ ocspCertStatus_good, /* cert is not revoked */
ocspCertStatus_revoked, /* cert is revoked */ ocspCertStatus_revoked, /* cert is revoked */
ocspCertStatus_unknown, /* cert was unknown to the responder */ ocspCertStatus_unknown, /* cert was unknown to the responder */
ocspCertStatus_other /* status was not an expected value */ ocspCertStatus_other /* status was not an expected value */
} ocspCertStatusType; } ocspCertStatusType;
/* /*
@ -327,13 +324,13 @@ typedef enum {
* gives more detailed information.) * gives more detailed information.)
*/ */
struct ocspCertStatusStr { struct ocspCertStatusStr {
ocspCertStatusType certStatusType; /* local; not part of encoding */ ocspCertStatusType certStatusType; /* local; not part of encoding */
union { union {
SECItem *goodInfo; /* when ocspCertStatus_good */ SECItem *goodInfo; /* when ocspCertStatus_good */
ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */ ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
SECItem *unknownInfo; /* when ocspCertStatus_unknown */ SECItem *unknownInfo; /* when ocspCertStatus_unknown */
SECItem *otherInfo; /* when ocspCertStatus_other */ SECItem *otherInfo; /* when ocspCertStatus_other */
} certStatusInfo; } certStatusInfo;
}; };
/* /*
@ -341,8 +338,8 @@ struct ocspCertStatusStr {
* was revoked and why. * was revoked and why.
*/ */
struct ocspRevokedInfoStr { struct ocspRevokedInfoStr {
SECItem revocationTime; /* a GeneralizedTime */ SECItem revocationTime; /* a GeneralizedTime */
SECItem *revocationReason; /* a CRLReason; ignored for now */ SECItem *revocationReason; /* a CRLReason; ignored for now */
}; };
/* /*
@ -353,7 +350,7 @@ struct ocspRevokedInfoStr {
*/ */
struct ocspServiceLocatorStr { struct ocspServiceLocatorStr {
CERTName *issuer; CERTName *issuer;
SECItem locator; /* DER encoded authInfoAccess extension from cert */ SECItem locator; /* DER encoded authInfoAccess extension from cert */
}; };
#endif /* _OCSPTI_H_ */ #endif /* _OCSPTI_H_ */

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

@ -12,203 +12,201 @@
SEC_ASN1_MKSUB(SEC_AnyTemplate) SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate) SEC_ASN1_MKSUB(SEC_BitStringTemplate)
extern void PrepareBitStringForEncoding (SECItem *bitMap, SECItem *value); extern void PrepareBitStringForEncoding(SECItem *bitMap, SECItem *value);
static const SEC_ASN1Template FullNameTemplate[] = { static const SEC_ASN1Template FullNameTemplate[] = {
{SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
offsetof (CRLDistributionPoint,derFullName), offsetof(CRLDistributionPoint, derFullName),
CERT_GeneralNamesTemplate} CERT_GeneralNamesTemplate }
}; };
static const SEC_ASN1Template RelativeNameTemplate[] = { static const SEC_ASN1Template RelativeNameTemplate[] = {
{SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
offsetof (CRLDistributionPoint,distPoint.relativeName), offsetof(CRLDistributionPoint, distPoint.relativeName),
CERT_RDNTemplate} CERT_RDNTemplate }
}; };
static const SEC_ASN1Template DistributionPointNameTemplate[] = { static const SEC_ASN1Template DistributionPointNameTemplate[] = {
{ SEC_ASN1_CHOICE, { SEC_ASN1_CHOICE,
offsetof(CRLDistributionPoint, distPointType), NULL, offsetof(CRLDistributionPoint, distPointType), NULL,
sizeof(CRLDistributionPoint) }, sizeof(CRLDistributionPoint) },
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
offsetof (CRLDistributionPoint, derFullName), offsetof(CRLDistributionPoint, derFullName),
CERT_GeneralNamesTemplate, generalName }, CERT_GeneralNamesTemplate, generalName },
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
offsetof (CRLDistributionPoint, distPoint.relativeName), offsetof(CRLDistributionPoint, distPoint.relativeName),
CERT_RDNTemplate, relativeDistinguishedName }, CERT_RDNTemplate, relativeDistinguishedName },
{ 0 } { 0 }
}; };
static const SEC_ASN1Template CRLDistributionPointTemplate[] = { static const SEC_ASN1Template CRLDistributionPointTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) }, { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0, SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
offsetof(CRLDistributionPoint,derDistPoint), offsetof(CRLDistributionPoint, derDistPoint),
SEC_ASN1_SUB(SEC_AnyTemplate)}, SEC_ASN1_SUB(SEC_AnyTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
offsetof(CRLDistributionPoint,bitsmap), offsetof(CRLDistributionPoint, bitsmap),
SEC_ASN1_SUB(SEC_BitStringTemplate) }, SEC_ASN1_SUB(SEC_BitStringTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
SEC_ASN1_CONSTRUCTED | 2, SEC_ASN1_CONSTRUCTED | 2,
offsetof(CRLDistributionPoint, derCrlIssuer), offsetof(CRLDistributionPoint, derCrlIssuer),
CERT_GeneralNamesTemplate}, CERT_GeneralNamesTemplate },
{ 0 } { 0 }
}; };
const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = { const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = {
{SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate} { SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate }
}; };
SECStatus SECStatus
CERT_EncodeCRLDistributionPoints (PLArenaPool *arena, CERT_EncodeCRLDistributionPoints(PLArenaPool *arena,
CERTCrlDistributionPoints *value, CERTCrlDistributionPoints *value,
SECItem *derValue) SECItem *derValue)
{ {
CRLDistributionPoint **pointList, *point; CRLDistributionPoint **pointList, *point;
PLArenaPool *ourPool = NULL; PLArenaPool *ourPool = NULL;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
PORT_Assert (derValue); PORT_Assert(derValue);
PORT_Assert (value && value->distPoints); PORT_Assert(value && value->distPoints);
do { do {
ourPool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); ourPool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (ourPool == NULL) { if (ourPool == NULL) {
rv = SECFailure; rv = SECFailure;
break; break;
} }
pointList = value->distPoints;
while (*pointList) {
point = *pointList;
point->derFullName = NULL;
point->derDistPoint.data = NULL;
switch (point->distPointType) { pointList = value->distPoints;
case generalName: while (*pointList) {
point->derFullName = cert_EncodeGeneralNames point = *pointList;
(ourPool, point->distPoint.fullName); point->derFullName = NULL;
point->derDistPoint.data = NULL;
if (!point->derFullName ||
!SEC_ASN1EncodeItem (ourPool, &point->derDistPoint,
point, FullNameTemplate))
rv = SECFailure;
break;
case relativeDistinguishedName: switch (point->distPointType) {
if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint, case generalName:
point, RelativeNameTemplate)) point->derFullName = cert_EncodeGeneralNames(ourPool, point->distPoint.fullName);
rv = SECFailure;
break;
default: if (!point->derFullName ||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); !SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
rv = SECFailure; point, FullNameTemplate))
break; rv = SECFailure;
} break;
if (rv != SECSuccess) case relativeDistinguishedName:
break; if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
point, RelativeNameTemplate))
rv = SECFailure;
break;
if (point->reasons.data) default:
PrepareBitStringForEncoding (&point->bitsmap, &point->reasons); PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
rv = SECFailure;
break;
}
if (point->crlIssuer) { if (rv != SECSuccess)
point->derCrlIssuer = cert_EncodeGeneralNames break;
(ourPool, point->crlIssuer);
if (!point->derCrlIssuer) { if (point->reasons.data)
rv = SECFailure; PrepareBitStringForEncoding(&point->bitsmap, &point->reasons);
break;
} if (point->crlIssuer) {
} point->derCrlIssuer = cert_EncodeGeneralNames(ourPool, point->crlIssuer);
++pointList; if (!point->derCrlIssuer) {
} rv = SECFailure;
if (rv != SECSuccess) break;
break; }
if (!SEC_ASN1EncodeItem(arena, derValue, value, }
CERTCRLDistributionPointsTemplate)) { ++pointList;
rv = SECFailure; }
break; if (rv != SECSuccess)
} break;
if (!SEC_ASN1EncodeItem(arena, derValue, value,
CERTCRLDistributionPointsTemplate)) {
rv = SECFailure;
break;
}
} while (0); } while (0);
PORT_FreeArena (ourPool, PR_FALSE); PORT_FreeArena(ourPool, PR_FALSE);
return rv; return rv;
} }
CERTCrlDistributionPoints * CERTCrlDistributionPoints *
CERT_DecodeCRLDistributionPoints (PLArenaPool *arena, SECItem *encodedValue) CERT_DecodeCRLDistributionPoints(PLArenaPool *arena, SECItem *encodedValue)
{ {
CERTCrlDistributionPoints *value = NULL; CERTCrlDistributionPoints *value = NULL;
CRLDistributionPoint **pointList, *point; CRLDistributionPoint **pointList, *point;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
SECItem newEncodedValue; SECItem newEncodedValue;
PORT_Assert (arena); PORT_Assert(arena);
do { do {
value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints); value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
if (value == NULL) { if (value == NULL) {
rv = SECFailure; rv = SECFailure;
break; break;
} }
/* copy the DER into the arena, since Quick DER returns data that points /* copy the DER into the arena, since Quick DER returns data that points
into the DER input, which may get freed by the caller */ into the DER input, which may get freed by the caller */
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
rv = SEC_QuickDERDecodeItem(arena, &value->distPoints, rv = SEC_QuickDERDecodeItem(arena, &value->distPoints,
CERTCRLDistributionPointsTemplate, &newEncodedValue); CERTCRLDistributionPointsTemplate, &newEncodedValue);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
pointList = value->distPoints; pointList = value->distPoints;
while (NULL != (point = *pointList)) { while (NULL != (point = *pointList)) {
/* get the data if the distributionPointName is not omitted */ /* get the data if the distributionPointName is not omitted */
if (point->derDistPoint.data != NULL) { if (point->derDistPoint.data != NULL) {
rv = SEC_QuickDERDecodeItem(arena, point, rv = SEC_QuickDERDecodeItem(arena, point,
DistributionPointNameTemplate, &(point->derDistPoint)); DistributionPointNameTemplate, &(point->derDistPoint));
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
switch (point->distPointType) { switch (point->distPointType) {
case generalName: case generalName:
point->distPoint.fullName = point->distPoint.fullName =
cert_DecodeGeneralNames(arena, point->derFullName); cert_DecodeGeneralNames(arena, point->derFullName);
rv = point->distPoint.fullName ? SECSuccess : SECFailure; rv = point->distPoint.fullName ? SECSuccess : SECFailure;
break; break;
case relativeDistinguishedName: case relativeDistinguishedName:
break; break;
default: default:
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
rv = SECFailure; rv = SECFailure;
break; break;
} /* end switch */ } /* end switch */
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
} /* end if */ } /* end if */
/* Get the reason code if it's not omitted in the encoding */ /* Get the reason code if it's not omitted in the encoding */
if (point->bitsmap.data != NULL) { if (point->bitsmap.data != NULL) {
SECItem bitsmap = point->bitsmap; SECItem bitsmap = point->bitsmap;
DER_ConvertBitString(&bitsmap); DER_ConvertBitString(&bitsmap);
rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap); rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
} }
/* Get the crl issuer name if it's not omitted in the encoding */ /* Get the crl issuer name if it's not omitted in the encoding */
if (point->derCrlIssuer != NULL) { if (point->derCrlIssuer != NULL) {
point->crlIssuer = cert_DecodeGeneralNames(arena, point->crlIssuer = cert_DecodeGeneralNames(arena,
point->derCrlIssuer); point->derCrlIssuer);
if (!point->crlIssuer) if (!point->crlIssuer)
break; break;
} }
++pointList; ++pointList;
} /* end while points remain */ } /* end while points remain */
} while (0); } while (0);
return (rv == SECSuccess ? value : NULL); return (rv == SECSuccess ? value : NULL);
} }

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

@ -6,12 +6,12 @@
* builtins/anchor.c * builtins/anchor.c
* *
* This file "anchors" the actual cryptoki entry points in this module's * This file "anchors" the actual cryptoki entry points in this module's
* shared library, which is required for dynamic loading. See the * shared library, which is required for dynamic loading. See the
* comments in nssck.api for more information. * comments in nssck.api for more information.
*/ */
#include "builtins.h" #include "builtins.h"
#define MODULE_NAME builtins #define MODULE_NAME builtins
#define INSTANCE_NAME (NSSCKMDInstance *)&nss_builtins_mdInstance #define INSTANCE_NAME (NSSCKMDInstance *) & nss_builtins_mdInstance
#include "nssck.api" #include "nssck.api"

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

@ -14,258 +14,250 @@
*/ */
struct builtinsFOStr { struct builtinsFOStr {
NSSArena *arena; NSSArena *arena;
CK_ULONG n; CK_ULONG n;
CK_ULONG i; CK_ULONG i;
builtinsInternalObject **objs; builtinsInternalObject **objs;
}; };
static void static void
builtins_mdFindObjects_Final builtins_mdFindObjects_Final(
( NSSCKMDFindObjects *mdFindObjects,
NSSCKMDFindObjects *mdFindObjects, NSSCKFWFindObjects *fwFindObjects,
NSSCKFWFindObjects *fwFindObjects, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance)
NSSCKFWInstance *fwInstance
)
{ {
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc; struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
NSSArena *arena = fo->arena; NSSArena *arena = fo->arena;
nss_ZFreeIf(fo->objs); nss_ZFreeIf(fo->objs);
nss_ZFreeIf(fo); nss_ZFreeIf(fo);
nss_ZFreeIf(mdFindObjects); nss_ZFreeIf(mdFindObjects);
if ((NSSArena *)NULL != arena) { if ((NSSArena *)NULL != arena) {
NSSArena_Destroy(arena); NSSArena_Destroy(arena);
} }
return; return;
} }
static NSSCKMDObject * static NSSCKMDObject *
builtins_mdFindObjects_Next builtins_mdFindObjects_Next(
( NSSCKMDFindObjects *mdFindObjects,
NSSCKMDFindObjects *mdFindObjects, NSSCKFWFindObjects *fwFindObjects,
NSSCKFWFindObjects *fwFindObjects, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, NSSArena *arena,
NSSArena *arena, CK_RV *pError)
CK_RV *pError
)
{ {
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc; struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
builtinsInternalObject *io; builtinsInternalObject *io;
if( fo->i == fo->n ) { if (fo->i == fo->n) {
*pError = CKR_OK; *pError = CKR_OK;
return (NSSCKMDObject *)NULL; return (NSSCKMDObject *)NULL;
} }
io = fo->objs[ fo->i ]; io = fo->objs[fo->i];
fo->i++; fo->i++;
return nss_builtins_CreateMDObject(arena, io, pError); return nss_builtins_CreateMDObject(arena, io, pError);
} }
static int static int
builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) { builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest)
{
unsigned char *start = src; unsigned char *start = src;
int len = 0; int len = 0;
if (*src ++ != 2) { if (*src++ != 2) {
return 0; return 0;
} }
len = *src++; len = *src++;
if (len & 0x80) { if (len & 0x80) {
int count = len & 0x7f; int count = len & 0x7f;
len =0; len = 0;
if (count+2 > size) { if (count + 2 > size) {
return 0; return 0;
} }
while (count-- > 0) { while (count-- > 0) {
len = (len << 8) | *src++; len = (len << 8) | *src++;
} }
} }
if (len + (src-start) != size) { if (len + (src - start) != size) {
return 0; return 0;
} }
*dest = src; *dest = src;
return len; return len;
} }
static CK_BBOOL static CK_BBOOL
builtins_attrmatch builtins_attrmatch(
( CK_ATTRIBUTE_PTR a,
CK_ATTRIBUTE_PTR a, const NSSItem *b)
const NSSItem *b
)
{ {
PRBool prb; PRBool prb;
if( a->ulValueLen != b->size ) { if (a->ulValueLen != b->size) {
/* match a decoded serial number */ /* match a decoded serial number */
if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) { if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
int len; int len;
unsigned char *data = NULL; unsigned char *data = NULL;
len = builtins_derUnwrapInt(b->data,b->size,&data); len = builtins_derUnwrapInt(b->data, b->size, &data);
if (data && if (data &&
(len == a->ulValueLen) && (len == a->ulValueLen) &&
nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) { nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
return CK_TRUE; return CK_TRUE;
} }
}
return CK_FALSE;
} }
return CK_FALSE;
}
prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL); prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
if( PR_TRUE == prb ) { if (PR_TRUE == prb) {
return CK_TRUE; return CK_TRUE;
} else { }
return CK_FALSE; else {
} return CK_FALSE;
}
} }
static CK_BBOOL static CK_BBOOL
builtins_match builtins_match(
( CK_ATTRIBUTE_PTR pTemplate,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
CK_ULONG ulAttributeCount, builtinsInternalObject *o)
builtinsInternalObject *o
)
{ {
CK_ULONG i; CK_ULONG i;
for( i = 0; i < ulAttributeCount; i++ ) { for (i = 0; i < ulAttributeCount; i++) {
CK_ULONG j; CK_ULONG j;
for( j = 0; j < o->n; j++ ) { for (j = 0; j < o->n; j++) {
if( o->types[j] == pTemplate[i].type ) { if (o->types[j] == pTemplate[i].type) {
if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) { if (CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j])) {
return CK_FALSE; return CK_FALSE;
} else { }
break; else {
break;
}
}
}
if (j == o->n) {
/* Loop ran to the end: no matching attribute */
return CK_FALSE;
} }
}
} }
if( j == o->n ) { /* Every attribute passed */
/* Loop ran to the end: no matching attribute */ return CK_TRUE;
return CK_FALSE;
}
}
/* Every attribute passed */
return CK_TRUE;
} }
NSS_IMPLEMENT NSSCKMDFindObjects * NSS_IMPLEMENT NSSCKMDFindObjects *
nss_builtins_FindObjectsInit nss_builtins_FindObjectsInit(
( NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, CK_ATTRIBUTE_PTR pTemplate,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
CK_ULONG ulAttributeCount, CK_RV *pError)
CK_RV *pError
)
{ {
/* This could be made more efficient. I'm rather rushed. */ /* This could be made more efficient. I'm rather rushed. */
NSSArena *arena; NSSArena *arena;
NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
/* /*
* 99% of the time we get 0 or 1 matches. So we start with a small * 99% of the time we get 0 or 1 matches. So we start with a small
* stack-allocated array to hold the matches and switch to a heap-allocated * stack-allocated array to hold the matches and switch to a heap-allocated
* array later if the number of matches exceeds STACK_BUF_LENGTH. * array later if the number of matches exceeds STACK_BUF_LENGTH.
*/ */
#define STACK_BUF_LENGTH 1 #define STACK_BUF_LENGTH 1
builtinsInternalObject *stackTemp[STACK_BUF_LENGTH]; builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
builtinsInternalObject **temp = stackTemp; builtinsInternalObject **temp = stackTemp;
PRBool tempIsHeapAllocated = PR_FALSE; PRBool tempIsHeapAllocated = PR_FALSE;
PRUint32 i; PRUint32 i;
arena = NSSArena_Create(); arena = NSSArena_Create();
if( (NSSArena *)NULL == arena ) { if ((NSSArena *)NULL == arena) {
goto loser; goto loser;
}
rv = nss_ZNEW(arena, NSSCKMDFindObjects);
if( (NSSCKMDFindObjects *)NULL == rv ) {
*pError = CKR_HOST_MEMORY;
goto loser;
}
fo = nss_ZNEW(arena, struct builtinsFOStr);
if( (struct builtinsFOStr *)NULL == fo ) {
*pError = CKR_HOST_MEMORY;
goto loser;
}
fo->arena = arena;
/* fo->n and fo->i are already zero */
rv->etc = (void *)fo;
rv->Final = builtins_mdFindObjects_Final;
rv->Next = builtins_mdFindObjects_Next;
rv->null = (void *)NULL;
for( i = 0; i < nss_builtins_nObjects; i++ ) {
builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
if( fo->n == STACK_BUF_LENGTH ) {
/* Switch from the small stack array to a heap-allocated array large
* enough to handle matches in all remaining cases. */
temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
fo->n + nss_builtins_nObjects - i);
if( (builtinsInternalObject **)NULL == temp ) {
*pError = CKR_HOST_MEMORY;
goto loser;
}
tempIsHeapAllocated = PR_TRUE;
(void)nsslibc_memcpy(temp, stackTemp,
sizeof(builtinsInternalObject *) * fo->n);
}
temp[ fo->n ] = o;
fo->n++;
} }
}
fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n); rv = nss_ZNEW(arena, NSSCKMDFindObjects);
if( (builtinsInternalObject **)NULL == fo->objs ) { if ((NSSCKMDFindObjects *)NULL == rv) {
*pError = CKR_HOST_MEMORY; *pError = CKR_HOST_MEMORY;
goto loser; goto loser;
} }
(void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n); fo = nss_ZNEW(arena, struct builtinsFOStr);
if (tempIsHeapAllocated) { if ((struct builtinsFOStr *)NULL == fo) {
nss_ZFreeIf(temp); *pError = CKR_HOST_MEMORY;
temp = (builtinsInternalObject **)NULL; goto loser;
} }
return rv; fo->arena = arena;
/* fo->n and fo->i are already zero */
loser: rv->etc = (void *)fo;
if (tempIsHeapAllocated) { rv->Final = builtins_mdFindObjects_Final;
nss_ZFreeIf(temp); rv->Next = builtins_mdFindObjects_Next;
} rv->null = (void *)NULL;
nss_ZFreeIf(fo);
nss_ZFreeIf(rv); for (i = 0; i < nss_builtins_nObjects; i++) {
if ((NSSArena *)NULL != arena) { builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
NSSArena_Destroy(arena);
} if (CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o)) {
return (NSSCKMDFindObjects *)NULL; if (fo->n == STACK_BUF_LENGTH) {
/* Switch from the small stack array to a heap-allocated array large
* enough to handle matches in all remaining cases. */
temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
fo->n + nss_builtins_nObjects - i);
if ((builtinsInternalObject **)NULL == temp) {
*pError =
CKR_HOST_MEMORY;
goto loser;
}
tempIsHeapAllocated = PR_TRUE;
(void)nsslibc_memcpy(temp, stackTemp,
sizeof(builtinsInternalObject *) * fo->n);
}
temp[fo->n] = o;
fo->n++;
}
}
fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
if ((builtinsInternalObject **)NULL == fo->objs) {
*pError = CKR_HOST_MEMORY;
goto loser;
}
(void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
if (tempIsHeapAllocated) {
nss_ZFreeIf(temp);
temp = (builtinsInternalObject **)NULL;
}
return rv;
loser:
if (tempIsHeapAllocated) {
nss_ZFreeIf(temp);
}
nss_ZFreeIf(fo);
nss_ZFreeIf(rv);
if ((NSSArena *)NULL != arena) {
NSSArena_Destroy(arena);
}
return (NSSCKMDFindObjects *)NULL;
} }

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

@ -7,7 +7,7 @@
/* /*
* builtins/instance.c * builtins/instance.c
* *
* This file implements the NSSCKMDInstance object for the * This file implements the NSSCKMDInstance object for the
* "builtin objects" cryptoki module. * "builtin objects" cryptoki module.
*/ */
@ -16,84 +16,72 @@
*/ */
static CK_ULONG static CK_ULONG
builtins_mdInstance_GetNSlots builtins_mdInstance_GetNSlots(
( NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_RV *pError)
CK_RV *pError
)
{ {
return (CK_ULONG)1; return (CK_ULONG)1;
} }
static CK_VERSION static CK_VERSION
builtins_mdInstance_GetCryptokiVersion builtins_mdInstance_GetCryptokiVersion(
( NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance)
NSSCKFWInstance *fwInstance
)
{ {
return nss_builtins_CryptokiVersion; return nss_builtins_CryptokiVersion;
} }
static NSSUTF8 * static NSSUTF8 *
builtins_mdInstance_GetManufacturerID builtins_mdInstance_GetManufacturerID(
( NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_RV *pError)
CK_RV *pError
)
{ {
return (NSSUTF8 *)nss_builtins_ManufacturerID; return (NSSUTF8 *)nss_builtins_ManufacturerID;
} }
static NSSUTF8 * static NSSUTF8 *
builtins_mdInstance_GetLibraryDescription builtins_mdInstance_GetLibraryDescription(
( NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_RV *pError)
CK_RV *pError
)
{ {
return (NSSUTF8 *)nss_builtins_LibraryDescription; return (NSSUTF8 *)nss_builtins_LibraryDescription;
} }
static CK_VERSION static CK_VERSION
builtins_mdInstance_GetLibraryVersion builtins_mdInstance_GetLibraryVersion(
( NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance)
NSSCKFWInstance *fwInstance
)
{ {
#define NSS_VERSION_VARIABLE __nss_builtins_version #define NSS_VERSION_VARIABLE __nss_builtins_version
#include "verref.h" #include "verref.h"
return nss_builtins_LibraryVersion; return nss_builtins_LibraryVersion;
} }
static CK_RV static CK_RV
builtins_mdInstance_GetSlots builtins_mdInstance_GetSlots(
( NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, NSSCKMDSlot *slots[])
NSSCKMDSlot *slots[]
)
{ {
slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot; slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
return CKR_OK; return CKR_OK;
} }
const NSSCKMDInstance const NSSCKMDInstance
nss_builtins_mdInstance = { nss_builtins_mdInstance = {
(void *)NULL, /* etc */ (void *)NULL, /* etc */
NULL, /* Initialize */ NULL, /* Initialize */
NULL, /* Finalize */ NULL, /* Finalize */
builtins_mdInstance_GetNSlots, builtins_mdInstance_GetNSlots,
builtins_mdInstance_GetCryptokiVersion, builtins_mdInstance_GetCryptokiVersion,
builtins_mdInstance_GetManufacturerID, builtins_mdInstance_GetManufacturerID,
builtins_mdInstance_GetLibraryDescription, builtins_mdInstance_GetLibraryDescription,
builtins_mdInstance_GetLibraryVersion, builtins_mdInstance_GetLibraryVersion,
NULL, /* ModuleHandlesSessionObjects -- defaults to false */ NULL, /* ModuleHandlesSessionObjects -- defaults to false */
builtins_mdInstance_GetSlots, builtins_mdInstance_GetSlots,
NULL, /* WaitForSlotEvent */ NULL, /* WaitForSlotEvent */
(void *)NULL /* null terminator */ (void *)NULL /* null terminator */
}; };

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

@ -24,199 +24,183 @@
*/ */
static CK_RV static CK_RV
builtins_mdObject_Destroy builtins_mdObject_Destroy(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance)
NSSCKFWInstance *fwInstance
)
{ {
return CKR_SESSION_READ_ONLY; return CKR_SESSION_READ_ONLY;
} }
static CK_BBOOL static CK_BBOOL
builtins_mdObject_IsTokenObject builtins_mdObject_IsTokenObject(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance)
NSSCKFWInstance *fwInstance
)
{ {
return CK_TRUE; return CK_TRUE;
} }
static CK_ULONG static CK_ULONG
builtins_mdObject_GetAttributeCount builtins_mdObject_GetAttributeCount(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_RV *pError)
CK_RV *pError
)
{ {
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc; builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
return io->n; return io->n;
} }
static CK_RV static CK_RV
builtins_mdObject_GetAttributeTypes builtins_mdObject_GetAttributeTypes(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_ATTRIBUTE_TYPE_PTR typeArray,
CK_ATTRIBUTE_TYPE_PTR typeArray, CK_ULONG ulCount)
CK_ULONG ulCount
)
{ {
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc; builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
CK_ULONG i; CK_ULONG i;
if( io->n != ulCount ) { if (io->n != ulCount) {
return CKR_BUFFER_TOO_SMALL; return CKR_BUFFER_TOO_SMALL;
} }
for( i = 0; i < io->n; i++ ) { for (i = 0; i < io->n; i++) {
typeArray[i] = io->types[i]; typeArray[i] = io->types[i];
} }
return CKR_OK; return CKR_OK;
} }
static CK_ULONG static CK_ULONG
builtins_mdObject_GetAttributeSize builtins_mdObject_GetAttributeSize(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_ATTRIBUTE_TYPE attribute,
CK_ATTRIBUTE_TYPE attribute, CK_RV *pError)
CK_RV *pError
)
{ {
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc; builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
CK_ULONG i; CK_ULONG i;
for( i = 0; i < io->n; i++ ) { for (i = 0; i < io->n; i++) {
if( attribute == io->types[i] ) { if (attribute == io->types[i]) {
return (CK_ULONG)(io->items[i].size); return (CK_ULONG)(io->items[i].size);
}
} }
}
*pError = CKR_ATTRIBUTE_TYPE_INVALID; *pError = CKR_ATTRIBUTE_TYPE_INVALID;
return 0; return 0;
} }
static NSSCKFWItem static NSSCKFWItem
builtins_mdObject_GetAttribute builtins_mdObject_GetAttribute(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_ATTRIBUTE_TYPE attribute,
CK_ATTRIBUTE_TYPE attribute, CK_RV *pError)
CK_RV *pError
)
{ {
NSSCKFWItem mdItem; NSSCKFWItem mdItem;
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc; builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
CK_ULONG i; CK_ULONG i;
mdItem.needsFreeing = PR_FALSE; mdItem.needsFreeing = PR_FALSE;
mdItem.item = (NSSItem*) NULL; mdItem.item = (NSSItem *)NULL;
for( i = 0; i < io->n; i++ ) { for (i = 0; i < io->n; i++) {
if( attribute == io->types[i] ) { if (attribute == io->types[i]) {
mdItem.item = (NSSItem*) &io->items[i]; mdItem.item = (NSSItem *)&io->items[i];
return mdItem; return mdItem;
}
} }
}
*pError = CKR_ATTRIBUTE_TYPE_INVALID; *pError = CKR_ATTRIBUTE_TYPE_INVALID;
return mdItem; return mdItem;
} }
static CK_ULONG static CK_ULONG
builtins_mdObject_GetObjectSize builtins_mdObject_GetObjectSize(
( NSSCKMDObject *mdObject,
NSSCKMDObject *mdObject, NSSCKFWObject *fwObject,
NSSCKFWObject *fwObject, NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_RV *pError)
CK_RV *pError
)
{ {
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc; builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
CK_ULONG i; CK_ULONG i;
CK_ULONG rv = sizeof(CK_ULONG); CK_ULONG rv = sizeof(CK_ULONG);
for( i = 0; i < io->n; i++ ) { for (i = 0; i < io->n; i++) {
rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size; rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
} }
return rv; return rv;
} }
static const NSSCKMDObject static const NSSCKMDObject
builtins_prototype_mdObject = { builtins_prototype_mdObject = {
(void *)NULL, /* etc */ (void *)NULL, /* etc */
NULL, /* Finalize */ NULL, /* Finalize */
builtins_mdObject_Destroy, builtins_mdObject_Destroy,
builtins_mdObject_IsTokenObject, builtins_mdObject_IsTokenObject,
builtins_mdObject_GetAttributeCount, builtins_mdObject_GetAttributeCount,
builtins_mdObject_GetAttributeTypes, builtins_mdObject_GetAttributeTypes,
builtins_mdObject_GetAttributeSize, builtins_mdObject_GetAttributeSize,
builtins_mdObject_GetAttribute, builtins_mdObject_GetAttribute,
NULL, /* FreeAttribute */ NULL, /* FreeAttribute */
NULL, /* SetAttribute */ NULL, /* SetAttribute */
builtins_mdObject_GetObjectSize, builtins_mdObject_GetObjectSize,
(void *)NULL /* null terminator */ (void *)NULL /* null terminator */
}; };
NSS_IMPLEMENT NSSCKMDObject * NSS_IMPLEMENT NSSCKMDObject *
nss_builtins_CreateMDObject nss_builtins_CreateMDObject(
( NSSArena *arena,
NSSArena *arena, builtinsInternalObject *io,
builtinsInternalObject *io, CK_RV *pError)
CK_RV *pError
)
{ {
if ( (void*)NULL == io->mdObject.etc) { if ((void *)NULL == io->mdObject.etc) {
(void) nsslibc_memcpy(&io->mdObject,&builtins_prototype_mdObject, (void)nsslibc_memcpy(&io->mdObject, &builtins_prototype_mdObject,
sizeof(builtins_prototype_mdObject)); sizeof(builtins_prototype_mdObject));
io->mdObject.etc = (void *)io; io->mdObject.etc = (void *)io;
} }
return &io->mdObject; return &io->mdObject;
} }

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

@ -7,69 +7,65 @@
/* /*
* builtins/session.c * builtins/session.c
* *
* This file implements the NSSCKMDSession object for the * This file implements the NSSCKMDSession object for the
* "builtin objects" cryptoki module. * "builtin objects" cryptoki module.
*/ */
static NSSCKMDFindObjects * static NSSCKMDFindObjects *
builtins_mdSession_FindObjectsInit builtins_mdSession_FindObjectsInit(
( NSSCKMDSession *mdSession,
NSSCKMDSession *mdSession, NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, NSSCKMDToken *mdToken,
NSSCKMDToken *mdToken, NSSCKFWToken *fwToken,
NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance,
NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance,
NSSCKFWInstance *fwInstance, CK_ATTRIBUTE_PTR pTemplate,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
CK_ULONG ulAttributeCount, CK_RV *pError)
CK_RV *pError
)
{ {
return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError); return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
} }
NSS_IMPLEMENT NSSCKMDSession * NSS_IMPLEMENT NSSCKMDSession *
nss_builtins_CreateSession nss_builtins_CreateSession(
( NSSCKFWSession *fwSession,
NSSCKFWSession *fwSession, CK_RV *pError)
CK_RV *pError
)
{ {
NSSArena *arena; NSSArena *arena;
NSSCKMDSession *rv; NSSCKMDSession *rv;
arena = NSSCKFWSession_GetArena(fwSession, pError); arena = NSSCKFWSession_GetArena(fwSession, pError);
if( (NSSArena *)NULL == arena ) { if ((NSSArena *)NULL == arena) {
return (NSSCKMDSession *)NULL; return (NSSCKMDSession *)NULL;
} }
rv = nss_ZNEW(arena, NSSCKMDSession); rv = nss_ZNEW(arena, NSSCKMDSession);
if( (NSSCKMDSession *)NULL == rv ) { if ((NSSCKMDSession *)NULL == rv) {
*pError = CKR_HOST_MEMORY; *pError = CKR_HOST_MEMORY;
return (NSSCKMDSession *)NULL; return (NSSCKMDSession *)NULL;
} }
/* /*
* rv was zeroed when allocated, so we only * rv was zeroed when allocated, so we only
* need to set the non-zero members. * need to set the non-zero members.
*/ */
rv->etc = (void *)fwSession; rv->etc = (void *)fwSession;
/* rv->Close */ /* rv->Close */
/* rv->GetDeviceError */ /* rv->GetDeviceError */
/* rv->Login */ /* rv->Login */
/* rv->Logout */ /* rv->Logout */
/* rv->InitPIN */ /* rv->InitPIN */
/* rv->SetPIN */ /* rv->SetPIN */
/* rv->GetOperationStateLen */ /* rv->GetOperationStateLen */
/* rv->GetOperationState */ /* rv->GetOperationState */
/* rv->SetOperationState */ /* rv->SetOperationState */
/* rv->CreateObject */ /* rv->CreateObject */
/* rv->CopyObject */ /* rv->CopyObject */
rv->FindObjectsInit = builtins_mdSession_FindObjectsInit; rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
/* rv->SeedRandom */ /* rv->SeedRandom */
/* rv->GetRandom */ /* rv->GetRandom */
/* rv->null */ /* rv->null */
return rv; return rv;
} }

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше