mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Revert 8406a2b981c5 to fix build bustage.
> Bug 1020695: Update Mozilla to use NSS 3.16.2 Beta 3. Includes fixes for > bug 1013088, bug 996237, bug 970539, bug 1016567, bug 485732, bug 334013, > bug 959864, bug 1016836, bug 1016811, bug 1018536, bug 996250, bug 1009227, > bug 963150.
This commit is contained in:
parent
a142a5db26
commit
27b5fea348
@ -1 +1 @@
|
||||
NSS_3_16_2_BETA3
|
||||
NSS_3_16_2_BETA2
|
||||
|
@ -92,10 +92,6 @@ static void Usage(char *progName)
|
||||
"-i input");
|
||||
fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
|
||||
"-o output");
|
||||
fprintf(stderr, "%-20s Wrap output in BEGIN/END lines and the given suffix\n",
|
||||
"-w suffix");
|
||||
fprintf(stderr, "%-20s (use \"c\" as a shortcut for suffix CERTIFICATE)\n",
|
||||
"");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@ -106,7 +102,6 @@ int main(int argc, char **argv)
|
||||
FILE *inFile, *outFile;
|
||||
PLOptState *optstate;
|
||||
PLOptStatus status;
|
||||
char *suffix = NULL;
|
||||
|
||||
inFile = 0;
|
||||
outFile = 0;
|
||||
@ -116,7 +111,7 @@ int main(int argc, char **argv)
|
||||
progName = progName ? progName+1 : argv[0];
|
||||
|
||||
/* Parse command line arguments */
|
||||
optstate = PL_CreateOptState(argc, argv, "i:o:w:");
|
||||
optstate = PL_CreateOptState(argc, argv, "i:o:");
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch (optstate->option) {
|
||||
default:
|
||||
@ -140,13 +135,6 @@ int main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (!strcmp(optstate->value, "c"))
|
||||
suffix = strdup("CERTIFICATE");
|
||||
else
|
||||
suffix = strdup(optstate->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == PL_OPT_BAD)
|
||||
@ -183,17 +171,11 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
outFile = stdout;
|
||||
}
|
||||
if (suffix) {
|
||||
fprintf(outFile, "-----BEGIN %s-----\n", suffix);
|
||||
}
|
||||
rv = encode_file(outFile, inFile);
|
||||
if (rv != SECSuccess) {
|
||||
fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
|
||||
progName, PORT_GetError(), errno);
|
||||
return -1;
|
||||
}
|
||||
if (suffix) {
|
||||
fprintf(outFile, "-----END %s-----\n", suffix);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include "xconst.h"
|
||||
#include "prprf.h"
|
||||
#include "certutil.h"
|
||||
#include "genname.h"
|
||||
#include "prnetdb.h"
|
||||
|
||||
#define GEN_BREAK(e) rv=e; break;
|
||||
|
||||
@ -667,213 +665,53 @@ AddNscpCertType (void *extHandle, const char *userSuppliedValue)
|
||||
|
||||
}
|
||||
|
||||
SECStatus
|
||||
GetOidFromString(PLArenaPool *arena, SECItem *to,
|
||||
const char *from, size_t fromLen)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECOidTag tag;
|
||||
SECOidData *coid;
|
||||
|
||||
/* try dotted form first */
|
||||
rv = SEC_StringToOID(arena, to, from, fromLen);
|
||||
if (rv == SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Check to see if it matches a name in our oid table.
|
||||
* SECOID_FindOIDByTag returns NULL if tag is out of bounds.
|
||||
*/
|
||||
tag = SEC_OID_UNKNOWN;
|
||||
coid = SECOID_FindOIDByTag(tag);
|
||||
for ( ; coid; coid = SECOID_FindOIDByTag(++tag)) {
|
||||
if (PORT_Strncasecmp(from, coid->desc, fromLen) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (coid == NULL) {
|
||||
/* none found */
|
||||
return SECFailure;
|
||||
}
|
||||
return SECITEM_CopyItem(arena, to, &coid->oid);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
AddSubjectAltNames(PLArenaPool *arena, CERTGeneralName **existingListp,
|
||||
const char *constNames, CERTGeneralNameType type)
|
||||
const char *names, CERTGeneralNameType type)
|
||||
{
|
||||
CERTGeneralName *nameList = NULL;
|
||||
CERTGeneralName *current = NULL;
|
||||
PRCList *prev = NULL;
|
||||
char *cp, *nextName = NULL;
|
||||
const char *cp;
|
||||
char *tbuf;
|
||||
SECStatus rv = SECSuccess;
|
||||
PRBool readTypeFromName = (PRBool) (type == 0);
|
||||
char *names = NULL;
|
||||
|
||||
if (constNames)
|
||||
names = PORT_Strdup(constNames);
|
||||
|
||||
if (names == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* walk down the comma separated list of names. NOTE: there is
|
||||
* no sanity checks to see if the email address look like
|
||||
* email addresses.
|
||||
*
|
||||
* Each name may optionally be prefixed with a type: string.
|
||||
* If it isn't, the type from the previous name will be used.
|
||||
* If there wasn't a previous name yet, the type given
|
||||
* as a parameter to this function will be used.
|
||||
* If the type value is zero (undefined), we'll fail.
|
||||
*/
|
||||
for (cp=names; cp; cp=nextName) {
|
||||
for (cp=names; cp; cp = PORT_Strchr(cp,',')) {
|
||||
int len;
|
||||
char *oidString;
|
||||
char *nextComma;
|
||||
CERTName *name;
|
||||
PRStatus status;
|
||||
unsigned char *data;
|
||||
PRNetAddr addr;
|
||||
char *end;
|
||||
|
||||
nextName = NULL;
|
||||
if (*cp == ',') {
|
||||
cp++;
|
||||
}
|
||||
nextComma = PORT_Strchr(cp, ',');
|
||||
if (nextComma) {
|
||||
*nextComma = 0;
|
||||
nextName = nextComma+1;
|
||||
}
|
||||
if ((*cp) == 0) {
|
||||
end = PORT_Strchr(cp,',');
|
||||
len = end ? end-cp : PORT_Strlen(cp);
|
||||
if (len <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (readTypeFromName) {
|
||||
char *save=cp;
|
||||
/* Because we already replaced nextComma with end-of-string,
|
||||
* a found colon belongs to the current name */
|
||||
cp = PORT_Strchr(cp, ':');
|
||||
if (cp) {
|
||||
*cp = 0;
|
||||
cp++;
|
||||
type = CERT_GetGeneralNameTypeFromString(save);
|
||||
if (*cp == 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (type == 0) {
|
||||
/* no type known yet */
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
cp = save;
|
||||
}
|
||||
}
|
||||
|
||||
current = PORT_ArenaZNew(arena, CERTGeneralName);
|
||||
tbuf = PORT_ArenaAlloc(arena,len+1);
|
||||
PORT_Memcpy(tbuf,cp,len);
|
||||
tbuf[len] = 0;
|
||||
current = (CERTGeneralName *) PORT_ZAlloc(sizeof(CERTGeneralName));
|
||||
if (!current) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
current->type = type;
|
||||
switch (type) {
|
||||
/* string types */
|
||||
case certRFC822Name:
|
||||
case certDNSName:
|
||||
case certURI:
|
||||
current->name.other.data =
|
||||
(unsigned char *) PORT_ArenaStrdup(arena,cp);
|
||||
current->name.other.len = PORT_Strlen(cp);
|
||||
break;
|
||||
/* unformated data types */
|
||||
case certX400Address:
|
||||
case certEDIPartyName:
|
||||
/* turn a string into a data and len */
|
||||
rv = SECFailure; /* punt on these for now */
|
||||
fprintf(stderr,"EDI Party Name and X.400 Address not supported\n");
|
||||
break;
|
||||
case certDirectoryName:
|
||||
/* certDirectoryName */
|
||||
name = CERT_AsciiToName(cp);
|
||||
if (name == NULL) {
|
||||
rv = SECFailure;
|
||||
fprintf(stderr, "Invalid Directory Name (\"%s\")\n", cp);
|
||||
break;
|
||||
}
|
||||
rv = CERT_CopyName(arena,¤t->name.directoryName,name);
|
||||
CERT_DestroyName(name);
|
||||
break;
|
||||
/* types that require more processing */
|
||||
case certIPAddress:
|
||||
/* convert the string to an ip address */
|
||||
status = PR_StringToNetAddr(cp, &addr);
|
||||
if (status != PR_SUCCESS) {
|
||||
rv = SECFailure;
|
||||
fprintf(stderr, "Invalid IP Address (\"%s\")\n", cp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (PR_NetAddrFamily(&addr) == PR_AF_INET) {
|
||||
len = sizeof(addr.inet.ip);
|
||||
data = (unsigned char *)&addr.inet.ip;
|
||||
} else if (PR_NetAddrFamily(&addr) == PR_AF_INET6) {
|
||||
len = sizeof(addr.ipv6.ip);
|
||||
data = (unsigned char *)&addr.ipv6.ip;
|
||||
} else {
|
||||
fprintf(stderr, "Invalid IP Family\n");
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
current->name.other.data = PORT_ArenaAlloc(arena, len);
|
||||
if (current->name.other.data == NULL) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
current->name.other.len = len;
|
||||
PORT_Memcpy(current->name.other.data,data, len);
|
||||
break;
|
||||
case certRegisterID:
|
||||
rv = GetOidFromString(arena, ¤t->name.other, cp, strlen(cp));
|
||||
break;
|
||||
case certOtherName:
|
||||
oidString = cp;
|
||||
cp = PORT_Strchr(cp,';');
|
||||
if (cp == NULL) {
|
||||
rv = SECFailure;
|
||||
fprintf(stderr, "missing name in other name\n");
|
||||
break;
|
||||
}
|
||||
*cp++ = 0;
|
||||
current->name.OthName.name.data =
|
||||
(unsigned char *) PORT_ArenaStrdup(arena,cp);
|
||||
if (current->name.OthName.name.data == NULL) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
current->name.OthName.name.len = PORT_Strlen(cp);
|
||||
rv = GetOidFromString(arena, ¤t->name.OthName.oid,
|
||||
oidString, strlen(oidString));
|
||||
break;
|
||||
default:
|
||||
rv = SECFailure;
|
||||
fprintf(stderr, "Missing or invalid Subject Alternate Name type\n");
|
||||
break;
|
||||
}
|
||||
if (rv == SECFailure) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
current->l.prev = prev;
|
||||
prev->next = &(current->l);
|
||||
} else {
|
||||
nameList = current;
|
||||
}
|
||||
current->type = type;
|
||||
current->name.other.data = (unsigned char *)tbuf;
|
||||
current->name.other.len = PORT_Strlen(tbuf);
|
||||
prev = &(current->l);
|
||||
}
|
||||
PORT_Free(names);
|
||||
/* at this point nameList points to the head of a doubly linked,
|
||||
* but not yet circular, list and current points to its tail. */
|
||||
if (rv == SECSuccess && nameList) {
|
||||
@ -911,12 +749,6 @@ AddDNSSubjectAlt(PLArenaPool *arena, CERTGeneralName **existingListp,
|
||||
return AddSubjectAltNames(arena, existingListp, dnsNames, certDNSName);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
AddGeneralSubjectAlt(PLArenaPool *arena, CERTGeneralName **existingListp,
|
||||
const char *altNames)
|
||||
{
|
||||
return AddSubjectAltNames(arena, existingListp, altNames, 0);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
AddBasicConstraint(void *extHandle)
|
||||
@ -1914,73 +1746,12 @@ AddInfoAccess(void *extHandle, PRBool addSIAExt, PRBool isCACert)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/* Example of valid input:
|
||||
* 1.2.3.4:critical:/tmp/abc,5.6.7.8:not-critical:/tmp/xyz
|
||||
*/
|
||||
static SECStatus
|
||||
parseNextGenericExt(const char *nextExtension, const char **oid, int *oidLen,
|
||||
const char **crit, int *critLen,
|
||||
const char **filename, int *filenameLen,
|
||||
const char **next)
|
||||
{
|
||||
const char *nextColon;
|
||||
const char *nextComma;
|
||||
const char *iter = nextExtension;
|
||||
|
||||
if (!iter || !*iter)
|
||||
return SECFailure;
|
||||
|
||||
/* Require colons at earlier positions than nextComma (or end of string ) */
|
||||
nextComma = strchr(iter, ',');
|
||||
|
||||
*oid = iter;
|
||||
nextColon = strchr(iter, ':');
|
||||
if (!nextColon || (nextComma && nextColon > nextComma))
|
||||
return SECFailure;
|
||||
*oidLen = (nextColon - *oid);
|
||||
|
||||
if (!*oidLen)
|
||||
return SECFailure;
|
||||
|
||||
iter = nextColon;
|
||||
++iter;
|
||||
|
||||
*crit = iter;
|
||||
nextColon = strchr(iter, ':');
|
||||
if (!nextColon || (nextComma && nextColon > nextComma))
|
||||
return SECFailure;
|
||||
*critLen = (nextColon - *crit);
|
||||
|
||||
if (!*critLen)
|
||||
return SECFailure;
|
||||
|
||||
iter = nextColon;
|
||||
++iter;
|
||||
|
||||
*filename = iter;
|
||||
if (nextComma) {
|
||||
*filenameLen = (nextComma - *filename);
|
||||
iter = nextComma;
|
||||
++iter;
|
||||
*next = iter;
|
||||
} else {
|
||||
*filenameLen = strlen(*filename);
|
||||
*next = NULL;
|
||||
}
|
||||
|
||||
if (!*filenameLen)
|
||||
return SECFailure;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
|
||||
certutilExtnList extList, const char *extGeneric)
|
||||
certutilExtnList extList)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
char *errstring = NULL;
|
||||
const char *nextExtension = NULL;
|
||||
|
||||
do {
|
||||
/* Add key usage extension */
|
||||
@ -2093,7 +1864,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
|
||||
}
|
||||
}
|
||||
|
||||
if (emailAddrs || dnsNames || extList[ext_subjectAltName].activated) {
|
||||
if (emailAddrs || dnsNames) {
|
||||
PLArenaPool *arena;
|
||||
CERTGeneralName *namelist = NULL;
|
||||
SECItem item = { 0, NULL, 0 };
|
||||
@ -2103,21 +1874,10 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
if (emailAddrs) {
|
||||
rv |= AddEmailSubjectAlt(arena, &namelist, emailAddrs);
|
||||
}
|
||||
rv = AddEmailSubjectAlt(arena, &namelist, emailAddrs);
|
||||
|
||||
if (dnsNames) {
|
||||
rv |= AddDNSSubjectAlt(arena, &namelist, dnsNames);
|
||||
}
|
||||
|
||||
if (extList[ext_subjectAltName].activated) {
|
||||
rv |= AddGeneralSubjectAlt(arena, &namelist,
|
||||
extList[ext_subjectAltName].arg);
|
||||
}
|
||||
rv |= AddDNSSubjectAlt(arena, &namelist, dnsNames);
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
rv = CERT_EncodeAltNameExtension(arena, namelist, &item);
|
||||
@ -2138,71 +1898,5 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "Problem creating %s extension", errstring);
|
||||
}
|
||||
|
||||
nextExtension = extGeneric;
|
||||
while (nextExtension && *nextExtension) {
|
||||
SECItem oid_item, value;
|
||||
PRBool isCritical;
|
||||
const char *oid, *crit, *filename, *next;
|
||||
int oidLen, critLen, filenameLen;
|
||||
PRFileDesc *inFile = NULL;
|
||||
char *zeroTerminatedFilename = NULL;
|
||||
|
||||
rv = parseNextGenericExt(nextExtension, &oid, &oidLen, &crit, &critLen,
|
||||
&filename, &filenameLen, &next);
|
||||
if (rv!= SECSuccess) {
|
||||
SECU_PrintError(progName,
|
||||
"error parsing generic extension parameter %s",
|
||||
nextExtension);
|
||||
break;
|
||||
}
|
||||
oid_item.data = NULL;
|
||||
oid_item.len = 0;
|
||||
rv = GetOidFromString(NULL, &oid_item, oid, oidLen);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "malformed extension OID %s", nextExtension);
|
||||
break;
|
||||
}
|
||||
if (!strncmp("critical", crit, critLen)) {
|
||||
isCritical = PR_TRUE;
|
||||
} else if (!strncmp("not-critical", crit, critLen)) {
|
||||
isCritical = PR_FALSE;
|
||||
} else {
|
||||
rv = SECFailure;
|
||||
SECU_PrintError(progName, "expected 'critical' or 'not-critical'");
|
||||
break;
|
||||
}
|
||||
zeroTerminatedFilename = PL_strndup(filename, filenameLen);
|
||||
if (!zeroTerminatedFilename) {
|
||||
rv = SECFailure;
|
||||
SECU_PrintError(progName, "out of memory");
|
||||
break;
|
||||
}
|
||||
rv = SECFailure;
|
||||
inFile = PR_Open(zeroTerminatedFilename, PR_RDONLY, 0);
|
||||
if (inFile) {
|
||||
rv = SECU_ReadDERFromFile(&value, inFile, PR_FALSE, PR_FALSE);
|
||||
PR_Close(inFile);
|
||||
inFile = NULL;
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "unable to read file %s",
|
||||
zeroTerminatedFilename);
|
||||
}
|
||||
PL_strfree(zeroTerminatedFilename);
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
rv = CERT_AddExtensionByOID(extHandle, &oid_item, &value, isCritical,
|
||||
PR_FALSE /*copyData*/);
|
||||
if (rv != SECSuccess) {
|
||||
SECITEM_FreeItem(&oid_item, PR_FALSE);
|
||||
SECITEM_FreeItem(&value, PR_FALSE);
|
||||
SECU_PrintError(progName, "failed to add extension %s", nextExtension);
|
||||
break;
|
||||
}
|
||||
nextExtension = next;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ static SECStatus
|
||||
CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
||||
SECOidTag hashAlgTag, CERTName *subject, char *phone, int ascii,
|
||||
const char *emailAddrs, const char *dnsNames,
|
||||
certutilExtnList extnList, const char *extGeneric,
|
||||
certutilExtnList extnList,
|
||||
/*out*/ SECItem *result)
|
||||
{
|
||||
CERTSubjectPublicKeyInfo *spki;
|
||||
@ -220,7 +220,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric)
|
||||
if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList)
|
||||
!= SECSuccess) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
@ -420,64 +420,11 @@ DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii)
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, PRBool ascii,
|
||||
SECItem *extensionOID, PRFileDesc *outfile)
|
||||
listCerts(CERTCertDBHandle *handle, char *name, char *email, PK11SlotInfo *slot,
|
||||
PRBool raw, PRBool ascii, PRFileDesc *outfile, void *pwarg)
|
||||
{
|
||||
SECItem data;
|
||||
PRInt32 numBytes;
|
||||
SECStatus rv = SECFailure;
|
||||
if (extensionOID) {
|
||||
int i;
|
||||
PRBool found = PR_FALSE;
|
||||
for (i=0; the_cert->extensions[i] != NULL; i++) {
|
||||
CERTCertExtension *extension = the_cert->extensions[i];
|
||||
if (SECITEM_CompareItem(&extension->id, extensionOID) == SECEqual) {
|
||||
found = PR_TRUE;
|
||||
numBytes = PR_Write(outfile, extension->value.data,
|
||||
extension->value.len);
|
||||
rv = SECSuccess;
|
||||
if (numBytes != (PRInt32) extension->value.len) {
|
||||
SECU_PrintSystemError(progName, "error writing extension");
|
||||
rv = SECFailure;
|
||||
}
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
SECU_PrintSystemError(progName, "extension not found");
|
||||
rv = SECFailure;
|
||||
}
|
||||
} else {
|
||||
data.data = the_cert->derCert.data;
|
||||
data.len = the_cert->derCert.len;
|
||||
if (ascii) {
|
||||
PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
|
||||
BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
|
||||
rv = SECSuccess;
|
||||
} else if (raw) {
|
||||
numBytes = PR_Write(outfile, data.data, data.len);
|
||||
rv = SECSuccess;
|
||||
if (numBytes != (PRInt32) data.len) {
|
||||
SECU_PrintSystemError(progName, "error writing raw cert");
|
||||
rv = SECFailure;
|
||||
}
|
||||
} else {
|
||||
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "problem printing certificate");
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
listCerts(CERTCertDBHandle *handle, char *name, char *email,
|
||||
PK11SlotInfo *slot, PRBool raw, PRBool ascii,
|
||||
SECItem *extensionOID,
|
||||
PRFileDesc *outfile, void *pwarg)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
CERTCertList *certs;
|
||||
CERTCertListNode *node;
|
||||
@ -514,13 +461,34 @@ listCerts(CERTCertDBHandle *handle, char *name, char *email,
|
||||
}
|
||||
for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID,
|
||||
outfile);
|
||||
the_cert = node->cert;
|
||||
/* now get the subjectList that matches this cert */
|
||||
data.data = the_cert->derCert.data;
|
||||
data.len = the_cert->derCert.len;
|
||||
if (ascii) {
|
||||
PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
|
||||
BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
|
||||
rv = SECSuccess;
|
||||
} else if (raw) {
|
||||
numBytes = PR_Write(outfile, data.data, data.len);
|
||||
if (numBytes != (PRInt32) data.len) {
|
||||
SECU_PrintSystemError(progName, "error writing raw cert");
|
||||
rv = SECFailure;
|
||||
}
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "problem printing certificate");
|
||||
}
|
||||
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (email) {
|
||||
CERTCertificate *the_cert;
|
||||
certs = PK11_FindCertsFromEmailAddress(email, NULL);
|
||||
if (!certs) {
|
||||
SECU_PrintError(progName,
|
||||
@ -530,8 +498,28 @@ listCerts(CERTCertDBHandle *handle, char *name, char *email,
|
||||
}
|
||||
for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID,
|
||||
outfile);
|
||||
the_cert = node->cert;
|
||||
/* now get the subjectList that matches this cert */
|
||||
data.data = the_cert->derCert.data;
|
||||
data.len = the_cert->derCert.len;
|
||||
if (ascii) {
|
||||
PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
|
||||
BTOA_DataToAscii(data.data, data.len),
|
||||
NS_CERT_TRAILER);
|
||||
rv = SECSuccess;
|
||||
} else if (raw) {
|
||||
numBytes = PR_Write(outfile, data.data, data.len);
|
||||
rv = SECSuccess;
|
||||
if (numBytes != (PRInt32) data.len) {
|
||||
SECU_PrintSystemError(progName, "error writing raw cert");
|
||||
rv = SECFailure;
|
||||
}
|
||||
} else {
|
||||
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "problem printing certificate");
|
||||
}
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
@ -559,9 +547,8 @@ listCerts(CERTCertDBHandle *handle, char *name, char *email,
|
||||
|
||||
static SECStatus
|
||||
ListCerts(CERTCertDBHandle *handle, char *nickname, char *email,
|
||||
PK11SlotInfo *slot, PRBool raw, PRBool ascii,
|
||||
SECItem *extensionOID,
|
||||
PRFileDesc *outfile, secuPWData *pwdata)
|
||||
PK11SlotInfo *slot, PRBool raw, PRBool ascii, PRFileDesc *outfile,
|
||||
secuPWData *pwdata)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
@ -582,8 +569,7 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, char *email,
|
||||
CERT_DestroyCertList(list);
|
||||
return SECSuccess;
|
||||
}
|
||||
rv = listCerts(handle, nickname, email, slot, raw, ascii,
|
||||
extensionOID, outfile, pwdata);
|
||||
rv = listCerts(handle, nickname, email, slot, raw, ascii, outfile, pwdata);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -629,15 +615,6 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
|
||||
case 'O':
|
||||
usage = certificateUsageStatusResponder;
|
||||
break;
|
||||
case 'L':
|
||||
usage = certificateUsageSSLCA;
|
||||
break;
|
||||
case 'A':
|
||||
usage = certificateUsageAnyCA;
|
||||
break;
|
||||
case 'Y':
|
||||
usage = certificateUsageVerifyCA;
|
||||
break;
|
||||
case 'C':
|
||||
usage = certificateUsageSSLClient;
|
||||
break;
|
||||
@ -1012,7 +989,7 @@ PrintSyntax(char *progName)
|
||||
FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
|
||||
FPS "\t%s -L [-n cert-name] [--email email-address] [-X] [-r] [-a]\n",
|
||||
progName);
|
||||
FPS "\t\t [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n");
|
||||
FPS "\t\t [-d certdir] [-P dbprefix]\n");
|
||||
FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
|
||||
progName);
|
||||
FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName);
|
||||
@ -1031,8 +1008,7 @@ PrintSyntax(char *progName)
|
||||
"\t\t [-p phone] [-1] [-2] [-3] [-4] [-5] [-6] [-7 emailAddrs]\n"
|
||||
"\t\t [-8 DNS-names]\n"
|
||||
"\t\t [--extAIA] [--extSIA] [--extCP] [--extPM] [--extPC] [--extIA]\n"
|
||||
"\t\t [--extSKID] [--extNC] [--extSAN type:name[,type:name]...]\n"
|
||||
"\t\t [--extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...]\n", progName);
|
||||
"\t\t [--extSKID] [--extNC]\n", progName);
|
||||
FPS "\t%s -U [-X] [-d certdir] [-P dbprefix]\n", progName);
|
||||
exit(1);
|
||||
}
|
||||
@ -1332,7 +1308,7 @@ static void luL(enum usage_level ul, const char *command)
|
||||
{
|
||||
int is_my_command = (command && 0 == strcmp(command, "L"));
|
||||
if (ul == usage_all || !command || is_my_command)
|
||||
FPS "%-15s List all certs, or print out a single named cert (or a subset)\n",
|
||||
FPS "%-15s List all certs, or print out a single named cert\n",
|
||||
"-L");
|
||||
if (ul == usage_selected && !is_my_command)
|
||||
return;
|
||||
@ -1351,9 +1327,6 @@ static void luL(enum usage_level ul, const char *command)
|
||||
" -r");
|
||||
FPS "%-20s For single cert, print ASCII encoding (RFC1113)\n",
|
||||
" -a");
|
||||
FPS "%-20s \n"
|
||||
"%-20s For single cert, print binary DER encoding of extension OID\n",
|
||||
" --dump-ext-val OID", "");
|
||||
FPS "\n");
|
||||
}
|
||||
|
||||
@ -1499,9 +1472,6 @@ static void luV(enum usage_level ul, const char *command)
|
||||
FPS "%-20s Specify certificate usage:\n", " -u certusage");
|
||||
FPS "%-25s C \t SSL Client\n", "");
|
||||
FPS "%-25s V \t SSL Server\n", "");
|
||||
FPS "%-25s L \t SSL CA\n", "");
|
||||
FPS "%-25s A \t Any CA\n", "");
|
||||
FPS "%-25s Y \t Verify CA\n", "");
|
||||
FPS "%-25s S \t Email signer\n", "");
|
||||
FPS "%-25s R \t Email Recipient\n", "");
|
||||
FPS "%-25s O \t OCSP status responder\n", "");
|
||||
@ -1668,18 +1638,6 @@ static void luS(enum usage_level ul, const char *command)
|
||||
" See -G for available key flag options");
|
||||
FPS "%-20s Create a name constraints extension\n",
|
||||
" --extNC ");
|
||||
FPS "%-20s \n"
|
||||
"%-20s Create a Subject Alt Name extension with one or multiple names\n",
|
||||
" --extSAN type:name[,type:name]...", "");
|
||||
FPS "%-20s - type: directory, dn, dns, edi, ediparty, email, ip, ipaddr,\n", "");
|
||||
FPS "%-20s other, registerid, rfc822, uri, x400, x400addr\n", "");
|
||||
FPS "%-20s \n"
|
||||
"%-20s Add one or multiple extensions that certutil cannot encode yet,\n"
|
||||
"%-20s by loading their encodings from external files.\n",
|
||||
" --extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...", "", "");
|
||||
FPS "%-20s - OID (example): 1.2.3.4\n", "");
|
||||
FPS "%-20s - critical-flag: critical or not-critical\n", "");
|
||||
FPS "%-20s - filename: full path to a file containing an encoded extension\n", "");
|
||||
FPS "\n");
|
||||
}
|
||||
|
||||
@ -1878,7 +1836,6 @@ CreateCert(
|
||||
PRBool ascii,
|
||||
PRBool selfsign,
|
||||
certutilExtnList extnList,
|
||||
const char *extGeneric,
|
||||
int certVersion,
|
||||
SECItem * certDER)
|
||||
{
|
||||
@ -1907,7 +1864,7 @@ CreateCert(
|
||||
GEN_BREAK (SECFailure)
|
||||
}
|
||||
|
||||
rv = AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric);
|
||||
rv = AddExtensions(extHandle, emailAddrs, dnsNames, extnList);
|
||||
if (rv != SECSuccess) {
|
||||
GEN_BREAK (SECFailure)
|
||||
}
|
||||
@ -2255,9 +2212,6 @@ enum certutilOpts {
|
||||
opt_KeyAttrFlags,
|
||||
opt_EmptyPassword,
|
||||
opt_CertVersion,
|
||||
opt_AddSubjectAltNameExt,
|
||||
opt_DumpExtensionValue,
|
||||
opt_GenericExtensions,
|
||||
opt_Help
|
||||
};
|
||||
|
||||
@ -2369,11 +2323,6 @@ secuCommandFlag options_init[] =
|
||||
"empty-password"},
|
||||
{ /* opt_CertVersion */ 0, PR_FALSE, 0, PR_FALSE,
|
||||
"certVersion"},
|
||||
{ /* opt_AddSubjectAltExt */ 0, PR_TRUE, 0, PR_FALSE, "extSAN"},
|
||||
{ /* opt_DumpExtensionValue */ 0, PR_TRUE, 0, PR_FALSE,
|
||||
"dump-ext-val"},
|
||||
{ /* opt_GenericExtensions */ 0, PR_TRUE, 0, PR_FALSE,
|
||||
"extGeneric"},
|
||||
};
|
||||
#define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0]))
|
||||
|
||||
@ -2714,10 +2663,9 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
return 255;
|
||||
}
|
||||
|
||||
/* if -L is given raw, ascii or dump mode, it must be for only one cert. */
|
||||
/* if -L is given raw or ascii mode, it must be for only one cert. */
|
||||
if (certutil.commands[cmd_ListCerts].activated &&
|
||||
(certutil.options[opt_ASCIIForIO].activated ||
|
||||
certutil.options[opt_DumpExtensionValue].activated ||
|
||||
certutil.options[opt_BinaryDER].activated) &&
|
||||
!certutil.options[opt_Nickname].activated) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
@ -3037,29 +2985,10 @@ merge_fail:
|
||||
|
||||
/* List certs (-L) */
|
||||
if (certutil.commands[cmd_ListCerts].activated) {
|
||||
if (certutil.options[opt_DumpExtensionValue].activated) {
|
||||
const char *oid_str;
|
||||
SECItem oid_item;
|
||||
SECStatus srv;
|
||||
oid_item.data = NULL;
|
||||
oid_item.len = 0;
|
||||
oid_str = certutil.options[opt_DumpExtensionValue].arg;
|
||||
srv = GetOidFromString(NULL, &oid_item, oid_str, strlen(oid_str));
|
||||
if (srv != SECSuccess) {
|
||||
SECU_PrintError(progName, "malformed extension OID %s",
|
||||
oid_str);
|
||||
goto shutdown;
|
||||
}
|
||||
rv = ListCerts(certHandle, name, email, slot,
|
||||
PR_TRUE /*binary*/, PR_FALSE /*ascii*/,
|
||||
&oid_item,
|
||||
outFile, &pwdata);
|
||||
} else {
|
||||
rv = ListCerts(certHandle, name, email, slot,
|
||||
certutil.options[opt_BinaryDER].activated,
|
||||
certutil.options[opt_ASCIIForIO].activated,
|
||||
NULL, outFile, &pwdata);
|
||||
}
|
||||
rv = ListCerts(certHandle, name, email, slot,
|
||||
certutil.options[opt_BinaryDER].activated,
|
||||
certutil.options[opt_ASCIIForIO].activated,
|
||||
outFile, &pwdata);
|
||||
goto shutdown;
|
||||
}
|
||||
if (certutil.commands[cmd_DumpChain].activated) {
|
||||
@ -3250,12 +3179,6 @@ merge_fail:
|
||||
certutil_extns[ext_extKeyUsage].arg =
|
||||
certutil.options[opt_AddCmdExtKeyUsageExt].arg;
|
||||
}
|
||||
certutil_extns[ext_subjectAltName].activated =
|
||||
certutil.options[opt_AddSubjectAltNameExt].activated;
|
||||
if (certutil_extns[ext_subjectAltName].activated) {
|
||||
certutil_extns[ext_subjectAltName].arg =
|
||||
certutil.options[opt_AddSubjectAltNameExt].arg;
|
||||
}
|
||||
|
||||
certutil_extns[ext_authInfoAcc].activated =
|
||||
certutil.options[opt_AddAuthInfoAccExt].activated;
|
||||
@ -3295,8 +3218,6 @@ merge_fail:
|
||||
certutil.options[opt_ExtendedEmailAddrs].arg,
|
||||
certutil.options[opt_ExtendedDNSNames].arg,
|
||||
certutil_extns,
|
||||
(certutil.options[opt_GenericExtensions].activated ?
|
||||
certutil.options[opt_GenericExtensions].arg : NULL),
|
||||
&certReqDER);
|
||||
if (rv)
|
||||
goto shutdown;
|
||||
@ -3319,8 +3240,6 @@ merge_fail:
|
||||
NULL,
|
||||
NULL,
|
||||
nullextnlist,
|
||||
(certutil.options[opt_GenericExtensions].activated ?
|
||||
certutil.options[opt_GenericExtensions].arg : NULL),
|
||||
&certReqDER);
|
||||
if (rv)
|
||||
goto shutdown;
|
||||
@ -3340,8 +3259,6 @@ merge_fail:
|
||||
certutil.commands[cmd_CreateNewCert].activated,
|
||||
certutil.options[opt_SelfSign].activated,
|
||||
certutil_extns,
|
||||
(certutil.options[opt_GenericExtensions].activated ?
|
||||
certutil.options[opt_GenericExtensions].arg : NULL),
|
||||
certVersion,
|
||||
&certDER);
|
||||
if (rv)
|
||||
|
@ -35,7 +35,6 @@ enum certutilExtns {
|
||||
ext_inhibitAnyPolicy,
|
||||
ext_subjectKeyID,
|
||||
ext_nameConstraints,
|
||||
ext_subjectAltName,
|
||||
ext_End
|
||||
};
|
||||
|
||||
@ -48,11 +47,7 @@ typedef ExtensionEntry certutilExtnList[ext_End];
|
||||
|
||||
extern SECStatus
|
||||
AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
|
||||
certutilExtnList extList, const char *extGeneric);
|
||||
|
||||
extern SECStatus
|
||||
GetOidFromString(PLArenaPool *arena, SECItem *to,
|
||||
const char *from, size_t fromLen);
|
||||
certutilExtnList extList);
|
||||
|
||||
#endif /* _CERTUTIL_H */
|
||||
|
||||
|
@ -1312,10 +1312,8 @@ main(int argc, char **argv)
|
||||
inFile = PR_Open(revoInfo->crlFilename, PR_RDONLY, 0);
|
||||
if (inFile) {
|
||||
rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
|
||||
PR_Close(inFile);
|
||||
inFile = NULL;
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
if (!inFile || rv != SECSuccess) {
|
||||
fprintf(stderr, "unable to read crl file %s\n",
|
||||
revoInfo->crlFilename);
|
||||
exit(1);
|
||||
|
@ -52,19 +52,6 @@ static char consoleName[] = {
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
static PRBool utf8DisplayEnabled = PR_FALSE;
|
||||
|
||||
void
|
||||
SECU_EnableUtf8Display(PRBool enable)
|
||||
{
|
||||
utf8DisplayEnabled = enable;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SECU_GetUtf8DisplayEnabled(void)
|
||||
{
|
||||
return utf8DisplayEnabled;
|
||||
}
|
||||
|
||||
static void
|
||||
secu_ClearPassword(char *p)
|
||||
@ -622,22 +609,12 @@ secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m,
|
||||
|
||||
for (i = 0; i < si->len; i++) {
|
||||
unsigned char val = si->data[i];
|
||||
unsigned char c;
|
||||
if (SECU_GetWrapEnabled() && column > 76) {
|
||||
SECU_Newline(out);
|
||||
SECU_Indent(out, level); column = level*INDENT_MULT;
|
||||
}
|
||||
|
||||
if (utf8DisplayEnabled) {
|
||||
if (val < 32)
|
||||
c = '.';
|
||||
else
|
||||
c = val;
|
||||
} else {
|
||||
c = printable[val];
|
||||
}
|
||||
fprintf(out,"%c", c);
|
||||
column++;
|
||||
fprintf(out,"%c", printable[val]); column++;
|
||||
}
|
||||
|
||||
if (quotes) {
|
||||
@ -2464,19 +2441,19 @@ loser:
|
||||
int
|
||||
SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
|
||||
{
|
||||
unsigned char fingerprint[SHA256_LENGTH];
|
||||
unsigned char fingerprint[20];
|
||||
char *fpStr = NULL;
|
||||
int err = PORT_GetError();
|
||||
SECStatus rv;
|
||||
SECItem fpItem;
|
||||
|
||||
/* Print SHA-256 fingerprint */
|
||||
/* print MD5 fingerprint */
|
||||
memset(fingerprint, 0, sizeof fingerprint);
|
||||
rv = PK11_HashBuf(SEC_OID_SHA256, fingerprint, derCert->data, derCert->len);
|
||||
rv = PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
|
||||
fpItem.data = fingerprint;
|
||||
fpItem.len = SHA256_LENGTH;
|
||||
fpItem.len = MD5_LENGTH;
|
||||
fpStr = CERT_Hexify(&fpItem, 1);
|
||||
SECU_Indent(out, level); fprintf(out, "%s (SHA-256):", m);
|
||||
SECU_Indent(out, level); fprintf(out, "%s (MD5):", m);
|
||||
if (SECU_GetWrapEnabled()) {
|
||||
fprintf(out, "\n");
|
||||
SECU_Indent(out, level+1);
|
||||
|
@ -139,9 +139,6 @@ SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
|
||||
extern PRBool SECU_GetWrapEnabled(void);
|
||||
extern void SECU_EnableWrap(PRBool enable);
|
||||
|
||||
extern PRBool SECU_GetUtf8DisplayEnabled(void);
|
||||
extern void SECU_EnableUtf8Display(PRBool enable);
|
||||
|
||||
/* revalidate the cert and print information about cert verification
|
||||
* failure at time == now */
|
||||
extern void
|
||||
|
@ -22,27 +22,22 @@ extern int fprintf(FILE *, char *, ...);
|
||||
static void Usage(char *progName)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-t type] [-a] [-i input] [-o output] [-w] [-u]\n",
|
||||
"Usage: %s -t type [-a] [-i input] [-o output] [-w]\n",
|
||||
progName);
|
||||
fprintf(stderr, "Pretty prints a file containing ASN.1 data in DER or ascii format.\n");
|
||||
fprintf(stderr, "%-14s Specify input and display type: %s (sk),\n",
|
||||
fprintf(stderr, "%-20s Specify the input type (must be one of %s,\n",
|
||||
"-t type", SEC_CT_PRIVATE_KEY);
|
||||
fprintf(stderr, "%-14s %s (pk), %s (c), %s (cr),\n", "", SEC_CT_PUBLIC_KEY,
|
||||
fprintf(stderr, "%-20s %s, %s, %s,\n", "", SEC_CT_PUBLIC_KEY,
|
||||
SEC_CT_CERTIFICATE, SEC_CT_CERTIFICATE_REQUEST);
|
||||
fprintf(stderr, "%-14s %s (ci), %s (p7), %s or %s (n).\n", "", SEC_CT_CERTIFICATE_ID,
|
||||
fprintf(stderr, "%-20s %s, %s, %s or %s)\n", "", SEC_CT_CERTIFICATE_ID,
|
||||
SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME);
|
||||
fprintf(stderr, "%-14s (Use either the long type name or the shortcut.)\n", "", SEC_CT_CERTIFICATE_ID,
|
||||
SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME);
|
||||
fprintf(stderr, "%-14s Input is in ascii encoded form (RFC1113)\n",
|
||||
fprintf(stderr, "%-20s Input is in ascii encoded form (RFC1113)\n",
|
||||
"-a");
|
||||
fprintf(stderr, "%-14s Define an input file to use (default is stdin)\n",
|
||||
fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
|
||||
"-i input");
|
||||
fprintf(stderr, "%-14s Define an output file to use (default is stdout)\n",
|
||||
fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
|
||||
"-o output");
|
||||
fprintf(stderr, "%-14s Don't wrap long output lines\n",
|
||||
fprintf(stderr, "%-20s Don't wrap long output lines\n",
|
||||
"-w");
|
||||
fprintf(stderr, "%-14s Use UTF-8 (default is to show non-ascii as .)\n",
|
||||
"-u");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@ -64,7 +59,7 @@ int main(int argc, char **argv)
|
||||
inFile = 0;
|
||||
outFile = 0;
|
||||
typeTag = 0;
|
||||
optstate = PL_CreateOptState(argc, argv, "at:i:o:uw");
|
||||
optstate = PL_CreateOptState(argc, argv, "at:i:o:w");
|
||||
while ( PL_GetNextOpt(optstate) == PL_OPT_OK ) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
@ -97,10 +92,6 @@ int main(int argc, char **argv)
|
||||
typeTag = strdup(optstate->value);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
SECU_EnableUtf8Display(PR_TRUE);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
wrap = PR_FALSE;
|
||||
break;
|
||||
@ -134,34 +125,27 @@ int main(int argc, char **argv)
|
||||
SECU_EnableWrap(wrap);
|
||||
|
||||
/* Pretty print it */
|
||||
if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0 ||
|
||||
PORT_Strcmp(typeTag, "c") == 0) {
|
||||
if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0) {
|
||||
rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
|
||||
SECU_PrintCertificate);
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0 ||
|
||||
PORT_Strcmp(typeTag, "ci") == 0) {
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0) {
|
||||
rv = SECU_PrintSignedContent(outFile, &data, 0, 0,
|
||||
SECU_PrintDumpDerIssuerAndSerial);
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0 ||
|
||||
PORT_Strcmp(typeTag, "cr") == 0) {
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0) {
|
||||
rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0,
|
||||
SECU_PrintCertificateRequest);
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_CRL) == 0) {
|
||||
} else if (PORT_Strcmp (typeTag, SEC_CT_CRL) == 0) {
|
||||
rv = SECU_PrintSignedData (outFile, &data, "CRL", 0, SECU_PrintCrl);
|
||||
#ifdef HAVE_EPV_TEMPLATE
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0 ||
|
||||
PORT_Strcmp(typeTag, "sk") == 0) {
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0) {
|
||||
rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0);
|
||||
#endif
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0 ||
|
||||
PORT_Strcmp (typeTag, "pk") == 0) {
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0) {
|
||||
rv = SECU_PrintSubjectPublicKeyInfo(outFile, &data, "Public Key", 0);
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_PKCS7) == 0 ||
|
||||
PORT_Strcmp (typeTag, "p7") == 0) {
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_PKCS7) == 0) {
|
||||
rv = SECU_PrintPKCS7ContentInfo(outFile, &data,
|
||||
"PKCS #7 Content Info", 0);
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_NAME) == 0 ||
|
||||
PORT_Strcmp (typeTag, "n") == 0) {
|
||||
} else if (PORT_Strcmp(typeTag, SEC_CT_NAME) == 0) {
|
||||
rv = SECU_PrintDERName(outFile, &data, "Name", 0);
|
||||
} else {
|
||||
fprintf(stderr, "%s: don't know how to print out '%s' files\n",
|
||||
|
@ -10,3 +10,4 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -28,12 +28,12 @@ static const NameToKind name2kinds[] = {
|
||||
* (See: http://www.iana.org/assignments/ldap-parameters)
|
||||
*/
|
||||
/* RFC 3280, 4630 MUST SUPPORT */
|
||||
{ "CN", 640, SEC_OID_AVA_COMMON_NAME, SEC_ASN1_DS},
|
||||
{ "CN", 64, SEC_OID_AVA_COMMON_NAME, SEC_ASN1_DS},
|
||||
{ "ST", 128, SEC_OID_AVA_STATE_OR_PROVINCE,
|
||||
SEC_ASN1_DS},
|
||||
{ "O", 128, SEC_OID_AVA_ORGANIZATION_NAME,
|
||||
{ "O", 64, SEC_OID_AVA_ORGANIZATION_NAME,
|
||||
SEC_ASN1_DS},
|
||||
{ "OU", 128, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
|
||||
{ "OU", 64, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
|
||||
SEC_ASN1_DS},
|
||||
{ "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER, SEC_ASN1_PRINTABLE_STRING},
|
||||
{ "C", 2, SEC_OID_AVA_COUNTRY_NAME, SEC_ASN1_PRINTABLE_STRING},
|
||||
@ -377,7 +377,7 @@ ParseRFC1485AVA(PLArenaPool *arena, const char **pbp, const char *endptr)
|
||||
char sep = 0;
|
||||
|
||||
char tagBuf[32];
|
||||
char valBuf[1024];
|
||||
char valBuf[384];
|
||||
|
||||
PORT_Assert(arena);
|
||||
if (SECSuccess != scanTag(pbp, endptr, tagBuf, sizeof tagBuf) ||
|
||||
@ -889,7 +889,7 @@ get_hex_string(SECItem *data)
|
||||
static SECStatus
|
||||
AppendAVA(stringBuf *bufp, CERTAVA *ava, CertStrictnessLevel strict)
|
||||
{
|
||||
#define TMPBUF_LEN 2048
|
||||
#define TMPBUF_LEN 384
|
||||
const NameToKind *pn2k = name2kinds;
|
||||
SECItem *avaValue = NULL;
|
||||
char *unknownTag = NULL;
|
||||
|
@ -137,39 +137,6 @@ const SEC_ASN1Template CERT_GeneralNamesTemplate[] = {
|
||||
};
|
||||
|
||||
|
||||
static struct {
|
||||
CERTGeneralNameType type;
|
||||
char *name;
|
||||
} typesArray[] = {
|
||||
{ certOtherName, "other" },
|
||||
{ certRFC822Name, "email" },
|
||||
{ certRFC822Name, "rfc822" },
|
||||
{ certDNSName, "dns" },
|
||||
{ certX400Address, "x400" },
|
||||
{ certX400Address, "x400addr" },
|
||||
{ certDirectoryName, "directory" },
|
||||
{ certDirectoryName, "dn" },
|
||||
{ certEDIPartyName, "edi" },
|
||||
{ certEDIPartyName, "ediparty" },
|
||||
{ certURI, "uri" },
|
||||
{ certIPAddress, "ip" },
|
||||
{ certIPAddress, "ipaddr" },
|
||||
{ certRegisterID, "registerid" }
|
||||
};
|
||||
|
||||
CERTGeneralNameType
|
||||
CERT_GetGeneralNameTypeFromString(const char *string)
|
||||
{
|
||||
int types_count = sizeof(typesArray)/sizeof(typesArray[0]);
|
||||
int i;
|
||||
|
||||
for (i=0; i < types_count; i++) {
|
||||
if (PORT_Strcasecmp(string, typesArray[i].name) == 0) {
|
||||
return typesArray[i].type;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CERTGeneralName *
|
||||
CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type)
|
||||
|
@ -26,9 +26,6 @@ cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName);
|
||||
extern SECStatus
|
||||
cert_DestroyGeneralNames(CERTGeneralName *name);
|
||||
|
||||
extern CERTGeneralNameType
|
||||
CERT_GetGeneralNameTypeFromString(const char *string);
|
||||
|
||||
extern SECStatus
|
||||
cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena,
|
||||
SECItem *dest);
|
||||
|
@ -56,7 +56,7 @@ extern SECItem *DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len);
|
||||
|
||||
/*
|
||||
** Create a new signature context used for signing a data stream.
|
||||
** "alg" the signature algorithm to use (e.g. SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION)
|
||||
** "alg" the signature algorithm to use (e.g. SEC_OID_RSA_WITH_MD5)
|
||||
** "privKey" the private key to use
|
||||
*/
|
||||
extern SGNContext *SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *privKey);
|
||||
|
@ -37,7 +37,7 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key)
|
||||
* PKCS #7 algTag if we were just going to change here you might
|
||||
* ask. Well the answer is for some cards we may have to do the
|
||||
* hashing on card. It may not support CKM_RSA_PKCS sign algorithm,
|
||||
* it may just support CKM_SHA1_RSA_PKCS and/or CKM_MD5_RSA_PKCS.
|
||||
* it may just support CKM_RSA_PKCS_WITH_SHA1 and/or CKM_RSA_PKCS_WITH_MD5.
|
||||
*/
|
||||
/* we have a private key, not a public key, so don't pass it in */
|
||||
rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg);
|
||||
|
@ -1406,17 +1406,6 @@ RSA_PrivateKeyCheck(RSAPrivateKey *key)
|
||||
CHECK_MPI_OK( mp_init(&d_q) );
|
||||
CHECK_MPI_OK( mp_init(&qInv) );
|
||||
CHECK_MPI_OK( mp_init(&res) );
|
||||
|
||||
if (!key->modulus.data || !key->prime1.data || !key->prime2.data ||
|
||||
!key->publicExponent.data || !key->privateExponent.data ||
|
||||
!key->exponent1.data || !key->exponent2.data ||
|
||||
!key->coefficient.data) {
|
||||
/*call RSA_PopulatePrivateKey first, if the application wishes to
|
||||
* recover these parameters */
|
||||
err = MP_BADARG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
SECITEM_TO_MPINT(key->modulus, &n);
|
||||
SECITEM_TO_MPINT(key->prime1, &p);
|
||||
SECITEM_TO_MPINT(key->prime2, &q);
|
||||
@ -1469,19 +1458,27 @@ RSA_PrivateKeyCheck(RSAPrivateKey *key)
|
||||
CHECK_MPI_OK( mp_mulmod(&d, &e, &qsub1, &res) );
|
||||
VERIFY_MPI_EQUAL_1(&res);
|
||||
/*
|
||||
* The following errors can be recovered from. However, the purpose of this
|
||||
* function is to check consistency, so they are not.
|
||||
* The following errors can be recovered from.
|
||||
*/
|
||||
/* d_p == d mod p-1 */
|
||||
CHECK_MPI_OK( mp_mod(&d, &psub1, &res) );
|
||||
VERIFY_MPI_EQUAL(&res, &d_p);
|
||||
if (mp_cmp(&d_p, &res) != 0) {
|
||||
/* swap in the correct value */
|
||||
CHECK_SEC_OK( swap_in_key_value(key->arena, &res, &key->exponent1) );
|
||||
}
|
||||
/* d_q == d mod q-1 */
|
||||
CHECK_MPI_OK( mp_mod(&d, &qsub1, &res) );
|
||||
VERIFY_MPI_EQUAL(&res, &d_q);
|
||||
if (mp_cmp(&d_q, &res) != 0) {
|
||||
/* swap in the correct value */
|
||||
CHECK_SEC_OK( swap_in_key_value(key->arena, &res, &key->exponent2) );
|
||||
}
|
||||
/* q * q**-1 == 1 mod p */
|
||||
CHECK_MPI_OK( mp_mulmod(&q, &qInv, &p, &res) );
|
||||
VERIFY_MPI_EQUAL_1(&res);
|
||||
|
||||
if (mp_cmp_d(&res, 1) != 0) {
|
||||
/* compute the correct value */
|
||||
CHECK_MPI_OK( mp_invmod(&q, &p, &qInv) );
|
||||
CHECK_SEC_OK( swap_in_key_value(key->arena, &qInv, &key->coefficient) );
|
||||
}
|
||||
cleanup:
|
||||
mp_clear(&n);
|
||||
mp_clear(&p);
|
||||
|
@ -1055,8 +1055,6 @@ SECMOD_InternaltoPubMechFlags;
|
||||
;+};
|
||||
;+NSS_3.16.2 { # NSS 3.16.2 release
|
||||
;+ global:
|
||||
CERT_AddExtensionByOID;
|
||||
CERT_GetGeneralNameTypeFromString;
|
||||
PK11_PubEncrypt;
|
||||
PK11_PrivDecrypt;
|
||||
;+ local:
|
||||
|
@ -981,15 +981,8 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
* CERTCertificate, and finish
|
||||
*/
|
||||
nssPKIObject_AddInstance(&c->object, certobj);
|
||||
/* nssTrustDomain_AddCertsToCache may release a reference to 'c' and
|
||||
* replace 'c' by a different value. So we add a reference to 'c' to
|
||||
* prevent 'c' from being destroyed. */
|
||||
nssCertificate_AddRef(c);
|
||||
nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
|
||||
/* XXX should we pass the original value of 'c' to
|
||||
* STAN_ForceCERTCertificateUpdate? */
|
||||
(void)STAN_ForceCERTCertificateUpdate(c);
|
||||
nssCertificate_Destroy(c);
|
||||
SECITEM_FreeItem(keyID,PR_TRUE);
|
||||
return SECSuccess;
|
||||
loser:
|
||||
|
@ -55,11 +55,6 @@ static const CK_C_INITIALIZE_ARGS secmodLockFunctions = {
|
||||
CKF_OS_LOCKING_OK
|
||||
,NULL
|
||||
};
|
||||
static const CK_C_INITIALIZE_ARGS secmodNoLockArgs = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
CKF_LIBRARY_CANT_CREATE_OS_THREADS
|
||||
,NULL
|
||||
};
|
||||
|
||||
static PRBool loadSingleThreadedModules = PR_TRUE;
|
||||
static PRBool enforceAlreadyInitializedError = PR_TRUE;
|
||||
@ -214,18 +209,12 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (mod->libraryParams == NULL) {
|
||||
if (mod->isThreadSafe) {
|
||||
pInitArgs = (void *) &secmodLockFunctions;
|
||||
} else {
|
||||
pInitArgs = NULL;
|
||||
}
|
||||
if (mod->isThreadSafe == PR_FALSE) {
|
||||
pInitArgs = NULL;
|
||||
} else if (mod->libraryParams == NULL) {
|
||||
pInitArgs = (void *) &secmodLockFunctions;
|
||||
} else {
|
||||
if (mod->isThreadSafe) {
|
||||
moduleArgs = secmodLockFunctions;
|
||||
} else {
|
||||
moduleArgs = secmodNoLockArgs;
|
||||
}
|
||||
moduleArgs = secmodLockFunctions;
|
||||
moduleArgs.LibraryParameters = (void *) mod->libraryParams;
|
||||
pInitArgs = &moduleArgs;
|
||||
}
|
||||
@ -262,30 +251,18 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
|
||||
}
|
||||
}
|
||||
if (crv != CKR_OK) {
|
||||
if (!mod->isThreadSafe ||
|
||||
if (pInitArgs == NULL ||
|
||||
crv == CKR_NETSCAPE_CERTDB_FAILED ||
|
||||
crv == CKR_NETSCAPE_KEYDB_FAILED) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return SECFailure;
|
||||
}
|
||||
/* If we had attempted to init a single threaded module "with"
|
||||
* parameters and it failed, should we retry "without" parameters?
|
||||
* (currently we don't retry in this scenario) */
|
||||
|
||||
if (!loadSingleThreadedModules) {
|
||||
PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
|
||||
return SECFailure;
|
||||
}
|
||||
/* If we arrive here, the module failed a ThreadSafe init. */
|
||||
mod->isThreadSafe = PR_FALSE;
|
||||
if (!mod->libraryParams) {
|
||||
pInitArgs = NULL;
|
||||
} else {
|
||||
moduleArgs = secmodNoLockArgs;
|
||||
moduleArgs.LibraryParameters = (void *) mod->libraryParams;
|
||||
pInitArgs = &moduleArgs;
|
||||
}
|
||||
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
|
||||
crv = PK11_GETTAB(mod)->C_Initialize(NULL);
|
||||
if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
|
||||
(!enforceAlreadyInitializedError)) {
|
||||
*alreadyLoaded = PR_TRUE;
|
||||
|
@ -4598,12 +4598,9 @@ nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
|
||||
|
||||
loser:
|
||||
if (handle->dbMon) {
|
||||
PZ_DestroyMonitor(handle->dbMon);
|
||||
handle->dbMon = NULL;
|
||||
}
|
||||
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
return(SECFailure);
|
||||
}
|
||||
|
@ -989,7 +989,7 @@ static NSSLOWKEYPrivateKey *
|
||||
sftk_mkPrivKey(SFTKObject *object,CK_KEY_TYPE key, CK_RV *rvp);
|
||||
|
||||
static SECStatus
|
||||
sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded);
|
||||
sftk_fillRSAPrivateKey(SFTKObject *object);
|
||||
|
||||
/*
|
||||
* check the consistancy and initialize a Private Key Object
|
||||
@ -1005,14 +1005,12 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
|
||||
CK_BBOOL derive = CK_TRUE;
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
PRBool createObjectInfo = PR_TRUE;
|
||||
PRBool fillPrivateKey = PR_FALSE;
|
||||
int missing_rsa_mod_component = 0;
|
||||
int missing_rsa_exp_component = 0;
|
||||
int missing_rsa_crt_component = 0;
|
||||
|
||||
|
||||
SECItem mod;
|
||||
CK_RV crv;
|
||||
SECStatus rv;
|
||||
|
||||
switch (key_type) {
|
||||
case CKK_RSA:
|
||||
@ -1047,19 +1045,19 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
|
||||
int have_exp = 2- missing_rsa_exp_component;
|
||||
int have_component = 5-
|
||||
(missing_rsa_exp_component+missing_rsa_mod_component);
|
||||
SECStatus rv;
|
||||
|
||||
if ((have_exp == 0) || (have_component < 3)) {
|
||||
/* nope, not enough to reconstruct the private key */
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
fillPrivateKey = PR_TRUE;
|
||||
}
|
||||
/*verify the parameters for consistency*/
|
||||
rv = sftk_verifyRSAPrivateKey(object, fillPrivateKey);
|
||||
if (rv != SECSuccess) {
|
||||
/*fill in the missing parameters */
|
||||
rv = sftk_fillRSAPrivateKey(object);
|
||||
if (rv != SECSuccess) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* make sure Netscape DB attribute is set correctly */
|
||||
crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);
|
||||
if (crv != CKR_OK) return crv;
|
||||
@ -1153,6 +1151,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
|
||||
if (sftk_isTrue(object,CKA_TOKEN)) {
|
||||
SFTKSlot *slot = session->slot;
|
||||
SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
|
||||
CK_RV crv;
|
||||
|
||||
if (keyHandle == NULL) {
|
||||
return CKR_TOKEN_WRITE_PROTECTED;
|
||||
@ -1943,11 +1942,10 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
|
||||
}
|
||||
|
||||
/*
|
||||
* If a partial RSA private key is present, fill in the rest if necessary,
|
||||
* and then verify the parameters are well-formed
|
||||
* we have a partial rsa private key, fill in the rest
|
||||
*/
|
||||
static SECStatus
|
||||
sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded)
|
||||
sftk_fillRSAPrivateKey(SFTKObject *object)
|
||||
{
|
||||
RSAPrivateKey tmpKey = { 0 };
|
||||
SFTKAttribute *modulus = NULL;
|
||||
@ -1955,9 +1953,6 @@ sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded)
|
||||
SFTKAttribute *prime2 = NULL;
|
||||
SFTKAttribute *privateExponent = NULL;
|
||||
SFTKAttribute *publicExponent = NULL;
|
||||
SFTKAttribute *exponent1 = NULL;
|
||||
SFTKAttribute *exponent2 = NULL;
|
||||
SFTKAttribute *coefficient = NULL;
|
||||
SECStatus rv;
|
||||
CK_RV crv;
|
||||
|
||||
@ -1988,82 +1983,44 @@ sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded)
|
||||
if (publicExponent) {
|
||||
tmpKey.publicExponent.data = publicExponent->attrib.pValue;
|
||||
tmpKey.publicExponent.len = publicExponent->attrib.ulValueLen;
|
||||
}
|
||||
exponent1 = sftk_FindAttribute(object, CKA_EXPONENT_1);
|
||||
if (exponent1) {
|
||||
tmpKey.exponent1.data = exponent1->attrib.pValue;
|
||||
tmpKey.exponent1.len = exponent1->attrib.ulValueLen;
|
||||
}
|
||||
exponent2 = sftk_FindAttribute(object, CKA_EXPONENT_2);
|
||||
if (exponent2) {
|
||||
tmpKey.exponent2.data = exponent2->attrib.pValue;
|
||||
tmpKey.exponent2.len = exponent2->attrib.ulValueLen;
|
||||
}
|
||||
coefficient = sftk_FindAttribute(object, CKA_COEFFICIENT);
|
||||
if (coefficient) {
|
||||
tmpKey.coefficient.data = coefficient->attrib.pValue;
|
||||
tmpKey.coefficient.len = coefficient->attrib.ulValueLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillIfNeeded) {
|
||||
/*
|
||||
* populate requires one exponent plus 2 other components to work.
|
||||
* we expected our caller to check that first. If that didn't happen,
|
||||
* populate will simply return an error here.
|
||||
*/
|
||||
rv = RSA_PopulatePrivateKey(&tmpKey);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
rv = RSA_PrivateKeyCheck(&tmpKey);
|
||||
/*
|
||||
* populate requires one exponent plus 2 other components to work.
|
||||
* we expected our caller to check that first. If that didn't happen,
|
||||
* populate will simply return an error here.
|
||||
*/
|
||||
rv = RSA_PopulatePrivateKey(&tmpKey);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* now that we have a fully populated key, set all our attribute values */
|
||||
rv = SECFailure;
|
||||
if (!modulus || modulus->attrib.pValue != tmpKey.modulus.data) {
|
||||
crv = sftk_forceAttribute(object,CKA_MODULUS,
|
||||
sftk_item_expand(&tmpKey.modulus));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!publicExponent ||
|
||||
publicExponent->attrib.pValue != tmpKey.publicExponent.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_PUBLIC_EXPONENT,
|
||||
sftk_item_expand(&tmpKey.publicExponent));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!privateExponent ||
|
||||
privateExponent->attrib.pValue != tmpKey.privateExponent.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_PRIVATE_EXPONENT,
|
||||
sftk_item_expand(&tmpKey.privateExponent));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!prime1 || prime1->attrib.pValue != tmpKey.prime1.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_PRIME_1,
|
||||
sftk_item_expand(&tmpKey.prime1));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!prime2 || prime2->attrib.pValue != tmpKey.prime2.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_PRIME_2,
|
||||
sftk_item_expand(&tmpKey.prime2));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!exponent1 || exponent1->attrib.pValue != tmpKey.exponent1.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_EXPONENT_1,
|
||||
sftk_item_expand(&tmpKey.exponent1));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!exponent1 || exponent1->attrib.pValue != tmpKey.exponent1.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_EXPONENT_2,
|
||||
sftk_item_expand(&tmpKey.exponent2));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
if (!exponent1 || exponent1->attrib.pValue != tmpKey.exponent1.data) {
|
||||
crv = sftk_forceAttribute(object, CKA_COEFFICIENT,
|
||||
sftk_item_expand(&tmpKey.coefficient));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
}
|
||||
crv = sftk_forceAttribute(object,CKA_MODULUS,
|
||||
sftk_item_expand(&tmpKey.modulus));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_PUBLIC_EXPONENT,
|
||||
sftk_item_expand(&tmpKey.publicExponent));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_PRIVATE_EXPONENT,
|
||||
sftk_item_expand(&tmpKey.privateExponent));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_PRIME_1,
|
||||
sftk_item_expand(&tmpKey.prime1));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_PRIME_2,
|
||||
sftk_item_expand(&tmpKey.prime2));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_EXPONENT_1,
|
||||
sftk_item_expand(&tmpKey.exponent1));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_EXPONENT_2,
|
||||
sftk_item_expand(&tmpKey.exponent2));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
crv = sftk_forceAttribute(object,CKA_COEFFICIENT,
|
||||
sftk_item_expand(&tmpKey.coefficient));
|
||||
if (crv != CKR_OK) goto loser;
|
||||
rv = SECSuccess;
|
||||
|
||||
/* we're done (one way or the other), clean up all our stuff */
|
||||
@ -2089,6 +2046,12 @@ loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Generate a low private key structure from an object */
|
||||
NSSLOWKEYPrivateKey *
|
||||
sftk_GetPrivKey(SFTKObject *object,CK_KEY_TYPE key_type, CK_RV *crvp)
|
||||
@ -3167,6 +3130,9 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
|
||||
|
||||
if (slot == NULL) return CKR_SLOT_ID_INVALID;
|
||||
|
||||
pInfo->firmwareVersion.major = 0;
|
||||
pInfo->firmwareVersion.minor = 0;
|
||||
|
||||
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,
|
||||
sizeof(pInfo->manufacturerID));
|
||||
PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,
|
||||
@ -3193,8 +3159,6 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
|
||||
/* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
|
||||
pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR;
|
||||
pInfo->hardwareVersion.minor = SOFTOKEN_VMINOR;
|
||||
pInfo->firmwareVersion.major = SOFTOKEN_VPATCH;
|
||||
pInfo->firmwareVersion.minor = SOFTOKEN_VBUILD;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
@ -412,9 +412,3 @@ ER3(SSL_ERROR_DIGEST_FAILURE, (SSL_ERROR_BASE + 127),
|
||||
|
||||
ER3(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 128),
|
||||
"Incorrect signature algorithm specified in a digitally-signed element.")
|
||||
|
||||
ER3(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK, (SSL_ERROR_BASE + 129),
|
||||
"The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.")
|
||||
|
||||
ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130),
|
||||
"The server supports no protocols that the client advertises in the ALPN extension.")
|
||||
|
@ -51,21 +51,16 @@ static const ssl3CipherSuite nonDTLSSuites[] = {
|
||||
*
|
||||
* TLS DTLS
|
||||
* 1.1 (0302) 1.0 (feff)
|
||||
* 1.2 (0303) 1.2 (fefd)
|
||||
*/
|
||||
SSL3ProtocolVersion
|
||||
dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
|
||||
{
|
||||
if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) {
|
||||
return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
|
||||
}
|
||||
if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE;
|
||||
}
|
||||
/* Anything other than TLS 1.1 is an error, so return
|
||||
* the invalid version ffff. */
|
||||
if (tlsv != SSL_LIBRARY_VERSION_TLS_1_1)
|
||||
return 0xffff;
|
||||
|
||||
/* Anything other than TLS 1.1 or 1.2 is an error, so return
|
||||
* the invalid version 0xffff. */
|
||||
return 0xffff;
|
||||
return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
|
||||
}
|
||||
|
||||
/* Map known DTLS versions to known TLS versions.
|
||||
@ -76,18 +71,14 @@ SSL3ProtocolVersion
|
||||
dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
|
||||
{
|
||||
if (MSB(dtlsv) == 0xff) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
|
||||
return SSL_LIBRARY_VERSION_TLS_1_1;
|
||||
}
|
||||
if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
|
||||
return SSL_LIBRARY_VERSION_TLS_1_2;
|
||||
}
|
||||
if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE)
|
||||
return SSL_LIBRARY_VERSION_TLS_1_1;
|
||||
|
||||
/* Return a fictional higher version than we know of */
|
||||
return SSL_LIBRARY_VERSION_TLS_1_2 + 1;
|
||||
return SSL_LIBRARY_VERSION_TLS_1_1 + 1;
|
||||
}
|
||||
|
||||
/* On this socket, Disable non-DTLS cipher suites in the argument's list */
|
||||
@ -97,9 +88,9 @@ ssl3_DisableNonDTLSSuites(sslSocket * ss)
|
||||
const ssl3CipherSuite * suite;
|
||||
|
||||
for (suite = nonDTLSSuites; *suite; ++suite) {
|
||||
SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
|
||||
SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
|
||||
|
||||
PORT_Assert(rv == SECSuccess); /* else is coding error */
|
||||
PORT_Assert(rv == SECSuccess); /* else is coding error */
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
@ -110,17 +101,17 @@ ssl3_DisableNonDTLSSuites(sslSocket * ss)
|
||||
*/
|
||||
static DTLSQueuedMessage *
|
||||
dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
|
||||
const unsigned char *data, PRUint32 len)
|
||||
const unsigned char *data, PRUint32 len)
|
||||
{
|
||||
DTLSQueuedMessage *msg = NULL;
|
||||
|
||||
msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage));
|
||||
if (!msg)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
msg->data = PORT_Alloc(len);
|
||||
if (!msg->data) {
|
||||
PORT_Free(msg);
|
||||
PORT_Free(msg);
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memcpy(msg->data, data, len);
|
||||
@ -141,7 +132,7 @@ static void
|
||||
dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
|
||||
{
|
||||
if (!msg)
|
||||
return;
|
||||
return;
|
||||
|
||||
PORT_ZFree(msg->data, msg->len);
|
||||
PORT_Free(msg);
|
||||
@ -160,9 +151,9 @@ dtls_FreeHandshakeMessages(PRCList *list)
|
||||
PRCList *cur_p;
|
||||
|
||||
while (!PR_CLIST_IS_EMPTY(list)) {
|
||||
cur_p = PR_LIST_TAIL(list);
|
||||
PR_REMOVE_LINK(cur_p);
|
||||
dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
|
||||
cur_p = PR_LIST_TAIL(list);
|
||||
PR_REMOVE_LINK(cur_p);
|
||||
dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,18 +204,18 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
}
|
||||
|
||||
/* Parse the header */
|
||||
type = buf.buf[0];
|
||||
type = buf.buf[0];
|
||||
message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
|
||||
message_seq = (buf.buf[4] << 8) | buf.buf[5];
|
||||
fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
|
||||
fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];
|
||||
|
||||
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
|
||||
if (message_length > MAX_HANDSHAKE_MSG_LEN) {
|
||||
(void)ssl3_DecodeError(ss);
|
||||
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
|
||||
if (message_length > MAX_HANDSHAKE_MSG_LEN) {
|
||||
(void)ssl3_DecodeError(ss);
|
||||
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
|
||||
return SECFailure;
|
||||
}
|
||||
#undef MAX_HANDSHAKE_MSG_LEN
|
||||
|
||||
buf.buf += 12;
|
||||
@ -238,7 +229,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
}
|
||||
|
||||
/* Sanity check the packet contents */
|
||||
if ((fragment_length + fragment_offset) > message_length) {
|
||||
if ((fragment_length + fragment_offset) > message_length) {
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
@ -254,8 +245,8 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
* This is the common case for short messages
|
||||
*/
|
||||
if ((message_seq == ss->ssl3.hs.recvMessageSeq)
|
||||
&& (fragment_offset == 0)
|
||||
&& (fragment_length == message_length)) {
|
||||
&& (fragment_offset == 0)
|
||||
&& (fragment_length == message_length)) {
|
||||
/* Complete next message. Process immediately */
|
||||
ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
|
||||
ss->ssl3.hs.msg_len = message_length;
|
||||
@ -263,14 +254,14 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
/* At this point we are advancing our state machine, so
|
||||
* we can free our last flight of messages */
|
||||
dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
|
||||
ss->ssl3.hs.recvdHighWater = -1;
|
||||
dtls_CancelTimer(ss);
|
||||
ss->ssl3.hs.recvdHighWater = -1;
|
||||
dtls_CancelTimer(ss);
|
||||
|
||||
/* Reset the timer to the initial value if the retry counter
|
||||
* is 0, per Sec. 4.2.4.1 */
|
||||
if (ss->ssl3.hs.rtRetries == 0) {
|
||||
ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
|
||||
}
|
||||
/* Reset the timer to the initial value if the retry counter
|
||||
* is 0, per Sec. 4.2.4.1 */
|
||||
if (ss->ssl3.hs.rtRetries == 0) {
|
||||
ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
|
||||
if (rv == SECFailure) {
|
||||
@ -278,68 +269,68 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (message_seq < ss->ssl3.hs.recvMessageSeq) {
|
||||
/* Case 3: we do an immediate retransmit if we're
|
||||
* in a waiting state*/
|
||||
if (ss->ssl3.hs.rtTimerCb == NULL) {
|
||||
/* Ignore */
|
||||
} else if (ss->ssl3.hs.rtTimerCb ==
|
||||
dtls_RetransmitTimerExpiredCb) {
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
|
||||
SSL_GETPID(), ss->fd));
|
||||
/* Check to see if we retransmitted recently. If so,
|
||||
* suppress the triggered retransmit. This avoids
|
||||
* retransmit wars after packet loss.
|
||||
* This is not in RFC 5346 but should be
|
||||
*/
|
||||
if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
|
||||
(ss->ssl3.hs.rtTimeoutMs / 4)) {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: Shortcutting retransmit timer",
|
||||
if (message_seq < ss->ssl3.hs.recvMessageSeq) {
|
||||
/* Case 3: we do an immediate retransmit if we're
|
||||
* in a waiting state*/
|
||||
if (ss->ssl3.hs.rtTimerCb == NULL) {
|
||||
/* Ignore */
|
||||
} else if (ss->ssl3.hs.rtTimerCb ==
|
||||
dtls_RetransmitTimerExpiredCb) {
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
|
||||
SSL_GETPID(), ss->fd));
|
||||
/* Check to see if we retransmitted recently. If so,
|
||||
* suppress the triggered retransmit. This avoids
|
||||
* retransmit wars after packet loss.
|
||||
* This is not in RFC 5346 but should be
|
||||
*/
|
||||
if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
|
||||
(ss->ssl3.hs.rtTimeoutMs / 4)) {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: Shortcutting retransmit timer",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
||||
/* Cancel the timer and call the CB,
|
||||
* which re-arms the timer */
|
||||
dtls_CancelTimer(ss);
|
||||
dtls_RetransmitTimerExpiredCb(ss);
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
} else {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: We just retransmitted. Ignoring.",
|
||||
/* Cancel the timer and call the CB,
|
||||
* which re-arms the timer */
|
||||
dtls_CancelTimer(ss);
|
||||
dtls_RetransmitTimerExpiredCb(ss);
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
} else {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: We just retransmitted. Ignoring.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
} else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
|
||||
/* Retransmit the messages and re-arm the timer
|
||||
* Note that we are not backing off the timer here.
|
||||
* The spec isn't clear and my reasoning is that this
|
||||
* may be a re-ordered packet rather than slowness,
|
||||
* so let's be aggressive. */
|
||||
dtls_CancelTimer(ss);
|
||||
rv = dtls_TransmitMessageFlight(ss);
|
||||
if (rv == SECSuccess) {
|
||||
rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
|
||||
}
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
break;
|
||||
}
|
||||
} else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
|
||||
/* Case 2
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
} else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
|
||||
/* Retransmit the messages and re-arm the timer
|
||||
* Note that we are not backing off the timer here.
|
||||
* The spec isn't clear and my reasoning is that this
|
||||
* may be a re-ordered packet rather than slowness,
|
||||
* so let's be aggressive. */
|
||||
dtls_CancelTimer(ss);
|
||||
rv = dtls_TransmitMessageFlight(ss);
|
||||
if (rv == SECSuccess) {
|
||||
rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
|
||||
}
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
break;
|
||||
}
|
||||
} else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
|
||||
/* Case 2
|
||||
*
|
||||
* Ignore this message. This means we don't handle out of
|
||||
* order complete messages that well, but we're still
|
||||
* compliant and this probably does not happen often
|
||||
* Ignore this message. This means we don't handle out of
|
||||
* order complete messages that well, but we're still
|
||||
* compliant and this probably does not happen often
|
||||
*
|
||||
* XXX OK for now. Maybe do something smarter at some point?
|
||||
*/
|
||||
} else {
|
||||
/* Case 1
|
||||
* XXX OK for now. Maybe do something smarter at some point?
|
||||
*/
|
||||
} else {
|
||||
/* Case 1
|
||||
*
|
||||
* Buffer the fragment for reassembly
|
||||
*/
|
||||
* Buffer the fragment for reassembly
|
||||
*/
|
||||
/* Make room for the message */
|
||||
if (ss->ssl3.hs.recvdHighWater == -1) {
|
||||
PRUint32 map_length = OFFSET_BYTE(message_length) + 1;
|
||||
@ -356,8 +347,8 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
/* Reset the reassembly map */
|
||||
ss->ssl3.hs.recvdHighWater = 0;
|
||||
PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
|
||||
ss->ssl3.hs.recvdFragments.space);
|
||||
ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
|
||||
ss->ssl3.hs.recvdFragments.space);
|
||||
ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
|
||||
ss->ssl3.hs.msg_len = message_length;
|
||||
}
|
||||
|
||||
@ -390,7 +381,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
* case of adjacent fragments received in sequence
|
||||
*/
|
||||
if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
|
||||
/* Either this is the adjacent fragment or an overlapping
|
||||
/* Either this is the adjacent fragment or an overlapping
|
||||
* fragment */
|
||||
ss->ssl3.hs.recvdHighWater = fragment_offset +
|
||||
fragment_length;
|
||||
@ -406,9 +397,9 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
/* Now figure out the new high water mark if appropriate */
|
||||
for (offset = ss->ssl3.hs.recvdHighWater;
|
||||
offset < ss->ssl3.hs.msg_len; offset++) {
|
||||
/* Note that this loop is not efficient, since it counts
|
||||
* bit by bit. If we have a lot of out-of-order packets,
|
||||
* we should optimize this */
|
||||
/* Note that this loop is not efficient, since it counts
|
||||
* bit by bit. If we have a lot of out-of-order packets,
|
||||
* we should optimize this */
|
||||
if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
|
||||
OFFSET_MASK(offset)) {
|
||||
ss->ssl3.hs.recvdHighWater++;
|
||||
@ -427,25 +418,25 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
if (rv == SECFailure)
|
||||
break; /* Skip rest of record */
|
||||
|
||||
/* At this point we are advancing our state machine, so
|
||||
* we can free our last flight of messages */
|
||||
dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
|
||||
dtls_CancelTimer(ss);
|
||||
/* At this point we are advancing our state machine, so
|
||||
* we can free our last flight of messages */
|
||||
dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
|
||||
dtls_CancelTimer(ss);
|
||||
|
||||
/* If there have been no retries this time, reset the
|
||||
* timer value to the default per Section 4.2.4.1 */
|
||||
if (ss->ssl3.hs.rtRetries == 0) {
|
||||
ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
|
||||
}
|
||||
/* If there have been no retries this time, reset the
|
||||
* timer value to the default per Section 4.2.4.1 */
|
||||
if (ss->ssl3.hs.rtRetries == 0) {
|
||||
ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf.buf += fragment_length;
|
||||
buf.buf += fragment_length;
|
||||
buf.len -= fragment_length;
|
||||
}
|
||||
|
||||
origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
|
||||
origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
|
||||
|
||||
/* XXX OK for now. In future handle rv == SECWouldBlock safely in order
|
||||
* to deal with asynchronous certificate verification */
|
||||
@ -470,10 +461,10 @@ SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
|
||||
msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn);
|
||||
|
||||
if (!msg) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
rv = SECFailure;
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
|
||||
PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -499,7 +490,7 @@ dtls_StageHandshakeMessage(sslSocket *ss)
|
||||
/* This function is sometimes called when no data is actually to
|
||||
* be staged, so just return SECSuccess. */
|
||||
if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
|
||||
return rv;
|
||||
return rv;
|
||||
|
||||
rv = dtls_QueueMessage(ss, content_handshake,
|
||||
ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);
|
||||
@ -531,11 +522,11 @@ dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
|
||||
rv = dtls_TransmitMessageFlight(ss);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
|
||||
ss->ssl3.hs.rtRetries = 0;
|
||||
rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
|
||||
}
|
||||
|
||||
if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
|
||||
ss->ssl3.hs.rtRetries = 0;
|
||||
rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -555,22 +546,22 @@ dtls_RetransmitTimerExpiredCb(sslSocket *ss)
|
||||
ss->ssl3.hs.rtRetries++;
|
||||
|
||||
if (!(ss->ssl3.hs.rtRetries % 3)) {
|
||||
/* If one of the messages was potentially greater than > MTU,
|
||||
* then downgrade. Do this every time we have retransmitted a
|
||||
* message twice, per RFC 6347 Sec. 4.1.1 */
|
||||
dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
|
||||
/* If one of the messages was potentially greater than > MTU,
|
||||
* then downgrade. Do this every time we have retransmitted a
|
||||
* message twice, per RFC 6347 Sec. 4.1.1 */
|
||||
dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
|
||||
}
|
||||
|
||||
|
||||
rv = dtls_TransmitMessageFlight(ss);
|
||||
if (rv == SECSuccess) {
|
||||
|
||||
/* Re-arm the timer */
|
||||
rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
|
||||
/* Re-arm the timer */
|
||||
rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
|
||||
}
|
||||
|
||||
if (rv == SECFailure) {
|
||||
/* XXX OK for now. In future maybe signal the stack that we couldn't
|
||||
* transmit. For now, let the read handle any real network errors */
|
||||
/* XXX OK for now. In future maybe signal the stack that we couldn't
|
||||
* transmit. For now, let the read handle any real network errors */
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,87 +591,87 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
||||
*/
|
||||
PORT_Assert(!ss->pendingBuf.len);
|
||||
for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight);
|
||||
msg_p != &ss->ssl3.hs.lastMessageFlight;
|
||||
msg_p = PR_NEXT_LINK(msg_p)) {
|
||||
msg_p != &ss->ssl3.hs.lastMessageFlight;
|
||||
msg_p = PR_NEXT_LINK(msg_p)) {
|
||||
DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;
|
||||
|
||||
/* The logic here is:
|
||||
*
|
||||
* 1. If this is a message that will not fit into the remaining
|
||||
* space, then flush.
|
||||
* 2. If the message will now fit into the remaining space,
|
||||
* 1. If this is a message that will not fit into the remaining
|
||||
* space, then flush.
|
||||
* 2. If the message will now fit into the remaining space,
|
||||
* encrypt, buffer, and loop.
|
||||
* 3. If the message will not fit, then fragment.
|
||||
*
|
||||
* At the end of the function, flush.
|
||||
* At the end of the function, flush.
|
||||
*/
|
||||
if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
|
||||
/* The message will not fit into the remaining space, so flush */
|
||||
rv = dtls_SendSavedWriteData(ss);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
/* The message will not fit into the remaining space, so flush */
|
||||
rv = dtls_SendSavedWriteData(ss);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
|
||||
room_left = ss->ssl3.mtu;
|
||||
}
|
||||
}
|
||||
|
||||
if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
|
||||
/* The message will fit, so encrypt and then continue with the
|
||||
* next packet */
|
||||
* next packet */
|
||||
sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
|
||||
msg->data, msg->len,
|
||||
ssl_SEND_FLAG_FORCE_INTO_BUFFER |
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
msg->data, msg->len,
|
||||
ssl_SEND_FLAG_FORCE_INTO_BUFFER |
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
if (sent != msg->len) {
|
||||
rv = SECFailure;
|
||||
if (sent != -1) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
rv = SECFailure;
|
||||
if (sent != -1) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
room_left = ss->ssl3.mtu - ss->pendingBuf.len;
|
||||
} else {
|
||||
/* The message will not fit, so fragment.
|
||||
*
|
||||
* XXX OK for now. Arrange to coalesce the last fragment
|
||||
* of this message with the next message if possible.
|
||||
* That would be more efficient.
|
||||
*/
|
||||
* XXX OK for now. Arrange to coalesce the last fragment
|
||||
* of this message with the next message if possible.
|
||||
* That would be more efficient.
|
||||
*/
|
||||
PRUint32 fragment_offset = 0;
|
||||
unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
|
||||
* plausible MTU */
|
||||
|
||||
/* Assert that we have already flushed */
|
||||
PORT_Assert(room_left == ss->ssl3.mtu);
|
||||
/* Assert that we have already flushed */
|
||||
PORT_Assert(room_left == ss->ssl3.mtu);
|
||||
|
||||
/* Case 3: We now need to fragment this message
|
||||
* DTLS only supports fragmenting handshaking messages */
|
||||
PORT_Assert(msg->type == content_handshake);
|
||||
|
||||
/* The headers consume 12 bytes so the smalles possible
|
||||
* message (i.e., an empty one) is 12 bytes
|
||||
*/
|
||||
PORT_Assert(msg->len >= 12);
|
||||
/* The headers consume 12 bytes so the smalles possible
|
||||
* message (i.e., an empty one) is 12 bytes
|
||||
*/
|
||||
PORT_Assert(msg->len >= 12);
|
||||
|
||||
while ((fragment_offset + 12) < msg->len) {
|
||||
PRUint32 fragment_len;
|
||||
const unsigned char *content = msg->data + 12;
|
||||
PRUint32 content_len = msg->len - 12;
|
||||
|
||||
/* The reason we use 8 here is that that's the length of
|
||||
* the new DTLS data that we add to the header */
|
||||
/* The reason we use 8 here is that that's the length of
|
||||
* the new DTLS data that we add to the header */
|
||||
fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
|
||||
content_len - fragment_offset);
|
||||
PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
|
||||
/* Make totally sure that we are within the buffer.
|
||||
* Note that the only way that fragment len could get
|
||||
* adjusted here is if
|
||||
PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
|
||||
/* Make totally sure that we are within the buffer.
|
||||
* Note that the only way that fragment len could get
|
||||
* adjusted here is if
|
||||
*
|
||||
* (a) we are in release mode so the PORT_Assert is compiled out
|
||||
* (b) either the MTU table is inconsistent with DTLS_MAX_MTU
|
||||
* or ss->ssl3.mtu has become corrupt.
|
||||
*/
|
||||
fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
|
||||
* (a) we are in release mode so the PORT_Assert is compiled out
|
||||
* (b) either the MTU table is inconsistent with DTLS_MAX_MTU
|
||||
* or ss->ssl3.mtu has become corrupt.
|
||||
*/
|
||||
fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
|
||||
|
||||
/* Construct an appropriate-sized fragment */
|
||||
/* Type, length, sequence */
|
||||
@ -700,25 +691,25 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
||||
fragment_len);
|
||||
|
||||
/*
|
||||
* Send the record. We do this in two stages
|
||||
* 1. Encrypt
|
||||
*/
|
||||
* Send the record. We do this in two stages
|
||||
* 1. Encrypt
|
||||
*/
|
||||
sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
|
||||
fragment, fragment_len + 12,
|
||||
ssl_SEND_FLAG_FORCE_INTO_BUFFER |
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
if (sent != (fragment_len + 12)) {
|
||||
rv = SECFailure;
|
||||
if (sent != -1) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* 2. Flush */
|
||||
rv = dtls_SendSavedWriteData(ss);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = SECFailure;
|
||||
if (sent != -1) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* 2. Flush */
|
||||
rv = dtls_SendSavedWriteData(ss);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
|
||||
fragment_offset += fragment_len;
|
||||
}
|
||||
@ -727,7 +718,7 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
||||
|
||||
/* Finally, we need to flush */
|
||||
if (rv == SECSuccess)
|
||||
rv = dtls_SendSavedWriteData(ss);
|
||||
rv = dtls_SendSavedWriteData(ss);
|
||||
|
||||
/* Give up the locks */
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
@ -749,19 +740,19 @@ SECStatus dtls_SendSavedWriteData(sslSocket *ss)
|
||||
|
||||
sent = ssl_SendSavedWriteData(ss);
|
||||
if (sent < 0)
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
|
||||
/* We should always have complete writes b/c datagram sockets
|
||||
* don't really block */
|
||||
if (ss->pendingBuf.len > 0) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
|
||||
return SECFailure;
|
||||
ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Update the largest message sent so we can adjust the MTU
|
||||
* estimate if necessary */
|
||||
if (sent > ss->ssl3.hs.maxMessageSent)
|
||||
ss->ssl3.hs.maxMessageSent = sent;
|
||||
ss->ssl3.hs.maxMessageSent = sent;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
@ -776,16 +767,16 @@ SECStatus dtls_SendSavedWriteData(sslSocket *ss)
|
||||
SECStatus
|
||||
dtls_CompressMACEncryptRecord(sslSocket * ss,
|
||||
DTLSEpoch epoch,
|
||||
PRBool use_epoch,
|
||||
PRBool use_epoch,
|
||||
SSL3ContentType type,
|
||||
const SSL3Opaque * pIn,
|
||||
PRUint32 contentLen,
|
||||
sslBuffer * wrBuf)
|
||||
const SSL3Opaque * pIn,
|
||||
PRUint32 contentLen,
|
||||
sslBuffer * wrBuf)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
ssl3CipherSpec * cwSpec;
|
||||
|
||||
ssl_GetSpecReadLock(ss); /********************************/
|
||||
ssl_GetSpecReadLock(ss); /********************************/
|
||||
|
||||
/* The reason for this switch-hitting code is that we might have
|
||||
* a flight of records spanning an epoch boundary, e.g.,
|
||||
@ -798,23 +789,23 @@ dtls_CompressMACEncryptRecord(sslSocket * ss,
|
||||
* about which epoch to use is carried with the record.
|
||||
*/
|
||||
if (use_epoch) {
|
||||
if (ss->ssl3.cwSpec->epoch == epoch)
|
||||
cwSpec = ss->ssl3.cwSpec;
|
||||
else if (ss->ssl3.pwSpec->epoch == epoch)
|
||||
cwSpec = ss->ssl3.pwSpec;
|
||||
else
|
||||
cwSpec = NULL;
|
||||
if (ss->ssl3.cwSpec->epoch == epoch)
|
||||
cwSpec = ss->ssl3.cwSpec;
|
||||
else if (ss->ssl3.pwSpec->epoch == epoch)
|
||||
cwSpec = ss->ssl3.pwSpec;
|
||||
else
|
||||
cwSpec = NULL;
|
||||
} else {
|
||||
cwSpec = ss->ssl3.cwSpec;
|
||||
cwSpec = ss->ssl3.cwSpec;
|
||||
}
|
||||
|
||||
if (cwSpec) {
|
||||
rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
|
||||
PR_FALSE, type, pIn, contentLen,
|
||||
wrBuf);
|
||||
PR_FALSE, type, pIn, contentLen,
|
||||
wrBuf);
|
||||
} else {
|
||||
PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
ssl_ReleaseSpecReadLock(ss); /************************************/
|
||||
|
||||
@ -847,9 +838,9 @@ SECStatus
|
||||
dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
|
||||
{
|
||||
if (backoff) {
|
||||
ss->ssl3.hs.rtTimeoutMs *= 2;
|
||||
if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
|
||||
ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
|
||||
ss->ssl3.hs.rtTimeoutMs *= 2;
|
||||
if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
|
||||
ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
return dtls_StartTimer(ss, cb);
|
||||
@ -877,18 +868,18 @@ void
|
||||
dtls_CheckTimer(sslSocket *ss)
|
||||
{
|
||||
if (!ss->ssl3.hs.rtTimerCb)
|
||||
return;
|
||||
return;
|
||||
|
||||
if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
|
||||
PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
|
||||
/* Timer has expired */
|
||||
DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
|
||||
PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
|
||||
/* Timer has expired */
|
||||
DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
|
||||
|
||||
/* Cancel the timer so that we can call the CB safely */
|
||||
dtls_CancelTimer(ss);
|
||||
|
||||
/* Cancel the timer so that we can call the CB safely */
|
||||
dtls_CancelTimer(ss);
|
||||
|
||||
/* Now call the CB */
|
||||
cb(ss);
|
||||
/* Now call the CB */
|
||||
cb(ss);
|
||||
}
|
||||
}
|
||||
|
||||
@ -937,17 +928,17 @@ dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
|
||||
int i;
|
||||
|
||||
if (advertised == 0) {
|
||||
ss->ssl3.mtu = COMMON_MTU_VALUES[0];
|
||||
SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
|
||||
return;
|
||||
ss->ssl3.mtu = COMMON_MTU_VALUES[0];
|
||||
SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
|
||||
if (COMMON_MTU_VALUES[i] <= advertised) {
|
||||
ss->ssl3.mtu = COMMON_MTU_VALUES[i];
|
||||
SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
|
||||
return;
|
||||
}
|
||||
if (COMMON_MTU_VALUES[i] <= advertised) {
|
||||
ss->ssl3.mtu = COMMON_MTU_VALUES[i];
|
||||
SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback */
|
||||
@ -962,57 +953,57 @@ dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
|
||||
SECStatus
|
||||
dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
||||
{
|
||||
int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
|
||||
int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
|
||||
SECStatus rv;
|
||||
PRInt32 temp;
|
||||
SECItem cookie = {siBuffer, NULL, 0};
|
||||
SSL3AlertDescription desc = illegal_parameter;
|
||||
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
|
||||
SSL_GETPID(), ss->fd));
|
||||
SSL_GETPID(), ss->fd));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
|
||||
if (ss->ssl3.hs.ws != wait_server_hello) {
|
||||
errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
|
||||
desc = unexpected_message;
|
||||
goto alert_loser;
|
||||
desc = unexpected_message;
|
||||
goto alert_loser;
|
||||
}
|
||||
|
||||
/* The version */
|
||||
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
|
||||
if (temp < 0) {
|
||||
goto loser; /* alert has been sent */
|
||||
goto loser; /* alert has been sent */
|
||||
}
|
||||
|
||||
if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE &&
|
||||
temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
|
||||
goto alert_loser;
|
||||
if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
|
||||
/* Note: this will need adjustment for DTLS 1.2 per Section 4.2.1 */
|
||||
goto alert_loser;
|
||||
}
|
||||
|
||||
/* The cookie */
|
||||
rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser; /* alert has been sent */
|
||||
goto loser; /* alert has been sent */
|
||||
}
|
||||
if (cookie.len > DTLS_COOKIE_BYTES) {
|
||||
desc = decode_error;
|
||||
goto alert_loser; /* malformed. */
|
||||
desc = decode_error;
|
||||
goto alert_loser; /* malformed. */
|
||||
}
|
||||
|
||||
PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
|
||||
ss->ssl3.hs.cookieLen = cookie.len;
|
||||
|
||||
|
||||
ssl_GetXmitBufLock(ss); /*******************************/
|
||||
ssl_GetXmitBufLock(ss); /*******************************/
|
||||
|
||||
/* Now re-send the client hello */
|
||||
rv = ssl3_SendClientHello(ss, PR_TRUE);
|
||||
|
||||
ssl_ReleaseXmitBufLock(ss); /*******************************/
|
||||
ssl_ReleaseXmitBufLock(ss); /*******************************/
|
||||
|
||||
if (rv == SECSuccess)
|
||||
return rv;
|
||||
return rv;
|
||||
|
||||
alert_loser:
|
||||
(void)SSL3_SendAlert(ss, alert_fatal, desc);
|
||||
@ -1051,14 +1042,14 @@ dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
|
||||
|
||||
/* Out of range to the left */
|
||||
if (seq < records->left) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Out of range to the right; since we advance the window on
|
||||
* receipt, that means that this packet has not been received
|
||||
* yet */
|
||||
if (seq > records->right)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
offset = seq % DTLS_RECVD_RECORDS_WINDOW;
|
||||
|
||||
@ -1075,34 +1066,34 @@ dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
|
||||
PRUint64 offset;
|
||||
|
||||
if (seq < records->left)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (seq > records->right) {
|
||||
PRUint64 new_left;
|
||||
PRUint64 new_right;
|
||||
PRUint64 right;
|
||||
PRUint64 new_left;
|
||||
PRUint64 new_right;
|
||||
PRUint64 right;
|
||||
|
||||
/* Slide to the right; this is the tricky part
|
||||
/* Slide to the right; this is the tricky part
|
||||
*
|
||||
* 1. new_top is set to have room for seq, on the
|
||||
* next byte boundary by setting the right 8
|
||||
* bits of seq
|
||||
* 1. new_top is set to have room for seq, on the
|
||||
* next byte boundary by setting the right 8
|
||||
* bits of seq
|
||||
* 2. new_left is set to compensate.
|
||||
* 3. Zero all bits between top and new_top. Since
|
||||
* this is a ring, this zeroes everything as-yet
|
||||
* unseen. Because we always operate on byte
|
||||
* boundaries, we can zero one byte at a time
|
||||
*/
|
||||
new_right = seq | 0x07;
|
||||
new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
|
||||
* unseen. Because we always operate on byte
|
||||
* boundaries, we can zero one byte at a time
|
||||
*/
|
||||
new_right = seq | 0x07;
|
||||
new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
|
||||
|
||||
for (right = records->right + 8; right <= new_right; right += 8) {
|
||||
offset = right % DTLS_RECVD_RECORDS_WINDOW;
|
||||
records->data[offset / 8] = 0;
|
||||
}
|
||||
for (right = records->right + 8; right <= new_right; right += 8) {
|
||||
offset = right % DTLS_RECVD_RECORDS_WINDOW;
|
||||
records->data[offset / 8] = 0;
|
||||
}
|
||||
|
||||
records->right = new_right;
|
||||
records->left = new_left;
|
||||
records->right = new_right;
|
||||
records->left = new_left;
|
||||
}
|
||||
|
||||
offset = seq % DTLS_RECVD_RECORDS_WINDOW;
|
||||
|
@ -633,7 +633,6 @@ ssl3_CipherSuiteAllowedForVersionRange(
|
||||
* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA: never implemented
|
||||
*/
|
||||
return vrange->min <= SSL_LIBRARY_VERSION_TLS_1_0;
|
||||
|
||||
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
|
||||
case TLS_RSA_WITH_AES_256_CBC_SHA256:
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
|
||||
@ -646,31 +645,6 @@ ssl3_CipherSuiteAllowedForVersionRange(
|
||||
case TLS_RSA_WITH_AES_128_GCM_SHA256:
|
||||
case TLS_RSA_WITH_NULL_SHA256:
|
||||
return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2;
|
||||
|
||||
/* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and
|
||||
* point formats.*/
|
||||
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
|
||||
case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
|
||||
case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
|
||||
case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
|
||||
case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
|
||||
case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
|
||||
case TLS_ECDH_RSA_WITH_NULL_SHA:
|
||||
case TLS_ECDH_RSA_WITH_RC4_128_SHA:
|
||||
case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
|
||||
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
|
||||
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
|
||||
case TLS_ECDHE_RSA_WITH_NULL_SHA:
|
||||
case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
|
||||
case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
|
||||
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
|
||||
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
|
||||
return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0;
|
||||
|
||||
default:
|
||||
return PR_TRUE;
|
||||
}
|
||||
@ -3497,14 +3471,6 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
||||
if (ws != wait_change_cipher) {
|
||||
if (IS_DTLS(ss)) {
|
||||
/* Ignore this because it's out of order. */
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: discard out of order "
|
||||
"DTLS change_cipher_spec",
|
||||
SSL_GETPID(), ss->fd));
|
||||
buf->len = 0;
|
||||
return SECSuccess;
|
||||
}
|
||||
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
|
||||
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
|
||||
return SECFailure;
|
||||
|
@ -56,14 +56,10 @@ static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
|
||||
PRUint16 ex_type, SECItem *data);
|
||||
static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
|
||||
PRUint16 ex_type, SECItem *data);
|
||||
static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
SECItem *data);
|
||||
static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
|
||||
PRUint32 maxBytes);
|
||||
static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
|
||||
@ -241,7 +237,6 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
||||
{ ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
|
||||
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
||||
{ ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
|
||||
{ ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
|
||||
{ ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
|
||||
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
|
||||
{ ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
|
||||
@ -564,8 +559,7 @@ ssl3_SendSessionTicketXtn(
|
||||
|
||||
/* handle an incoming Next Protocol Negotiation extension. */
|
||||
static SECStatus
|
||||
ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type,
|
||||
SECItem *data)
|
||||
ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
||||
{
|
||||
if (ss->firstHsDone || data->len != 0) {
|
||||
/* Clients MUST send an empty NPN extension, if any. */
|
||||
@ -610,93 +604,14 @@ ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* protocol selection handler for ALPN (server side) and NPN (client side) */
|
||||
static SECStatus
|
||||
ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
||||
ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
SECItem *data)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned char resultBuffer[255];
|
||||
SECItem result = { siBuffer, resultBuffer, 0 };
|
||||
|
||||
rv = ssl3_ValidateNextProtoNego(data->data, data->len);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
PORT_Assert(ss->nextProtoCallback);
|
||||
rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
|
||||
result.data, &result.len, sizeof resultBuffer);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
/* If the callback wrote more than allowed to |result| it has corrupted our
|
||||
* stack. */
|
||||
if (result.len > sizeof resultBuffer) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (ex_type == ssl_app_layer_protocol_xtn &&
|
||||
ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
|
||||
/* The callback might say OK, but then it's picked a default.
|
||||
* That's OK for NPN, but not ALPN. */
|
||||
SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
|
||||
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
|
||||
(void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
||||
|
||||
SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
|
||||
return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
|
||||
}
|
||||
|
||||
/* handle an incoming ALPN extension at the server */
|
||||
static SECStatus
|
||||
ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
||||
{
|
||||
int count;
|
||||
SECStatus rv;
|
||||
|
||||
/* We expressly don't want to allow ALPN on renegotiation,
|
||||
* despite it being permitted by the spec. */
|
||||
if (ss->firstHsDone || data->len == 0) {
|
||||
/* Clients MUST send a non-empty ALPN extension. */
|
||||
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* unlike NPN, ALPN has extra redundant length information so that
|
||||
* the extension is the same in both ClientHello and ServerHello */
|
||||
count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
|
||||
if (count < 0) {
|
||||
return SECFailure; /* fatal alert was sent */
|
||||
}
|
||||
if (count != data->len) {
|
||||
return ssl3_DecodeError(ss);
|
||||
}
|
||||
|
||||
if (!ss->nextProtoCallback) {
|
||||
/* we're not configured for it */
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
rv = ssl3_SelectAppProtocol(ss, ex_type, data);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* prepare to send back a response, if we negotiated */
|
||||
if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) {
|
||||
return ssl3_RegisterServerHelloExtensionSender(
|
||||
ss, ex_type, ssl3_ServerSendAppProtoXtn);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
SECItem *data)
|
||||
{
|
||||
PORT_Assert(!ss->firstHsDone);
|
||||
|
||||
if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
|
||||
@ -710,16 +625,37 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* We should only get this call if we sent the extension, so
|
||||
* ss->nextProtoCallback needs to be non-NULL. However, it is possible
|
||||
* that an application erroneously cleared the callback between the time
|
||||
* we sent the ClientHello and now. */
|
||||
rv = ssl3_ValidateNextProtoNego(data->data, data->len);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* ss->nextProtoCallback cannot normally be NULL if we negotiated the
|
||||
* extension. However, It is possible that an application erroneously
|
||||
* cleared the callback between the time we sent the ClientHello and now.
|
||||
*/
|
||||
PORT_Assert(ss->nextProtoCallback != NULL);
|
||||
if (!ss->nextProtoCallback) {
|
||||
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
|
||||
/* XXX Use a better error code. This is an application error, not an
|
||||
* NSS bug. */
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return ssl3_SelectAppProtocol(ss, ex_type, data);
|
||||
rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
|
||||
result.data, &result.len, sizeof resultBuffer);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
/* If the callback wrote more than allowed to |result| it has corrupted our
|
||||
* stack. */
|
||||
if (result.len > sizeof resultBuffer) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
||||
|
||||
SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
|
||||
return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
@ -860,48 +796,6 @@ loser:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static PRInt32
|
||||
ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
||||
{
|
||||
PRInt32 extension_length;
|
||||
|
||||
/* we're in over our heads if any of these fail */
|
||||
PORT_Assert(ss->opt.enableALPN);
|
||||
PORT_Assert(ss->ssl3.nextProto.data);
|
||||
PORT_Assert(ss->ssl3.nextProto.len > 0);
|
||||
PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED);
|
||||
PORT_Assert(!ss->firstHsDone);
|
||||
|
||||
extension_length = 2 /* extension type */ + 2 /* extension length */ +
|
||||
2 /* protocol name list */ + 1 /* name length */ +
|
||||
ss->ssl3.nextProto.len;
|
||||
|
||||
if (append && maxBytes >= extension_length) {
|
||||
SECStatus rv;
|
||||
rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
|
||||
if (rv != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
|
||||
if (rv != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2);
|
||||
if (rv != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
|
||||
ss->ssl3.nextProto.len, 1);
|
||||
if (rv != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
} else if (maxBytes < extension_length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return extension_length;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
|
||||
SECItem *data)
|
||||
|
@ -106,8 +106,7 @@ typedef enum {
|
||||
certificate_unobtainable = 111,
|
||||
unrecognized_name = 112,
|
||||
bad_certificate_status_response = 113,
|
||||
bad_certificate_hash_value = 114,
|
||||
no_application_protocol = 120
|
||||
bad_certificate_hash_value = 114
|
||||
|
||||
} SSL3AlertDescription;
|
||||
|
||||
|
@ -193,9 +193,6 @@ SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 126),
|
||||
SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 127),
|
||||
SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128),
|
||||
|
||||
SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129),
|
||||
SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
|
||||
|
||||
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
||||
} SSLErrorCodes;
|
||||
#endif /* NO_SECURITY_ERROR_ENUM */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Various and sundry protocol constants. DON'T CHANGE THESE. These values
|
||||
* Various and sundry protocol constants. DON'T CHANGE THESE. These values
|
||||
* are mostly defined by the SSL2, SSL3, or TLS protocol specifications.
|
||||
* Cipher kinds and ciphersuites are part of the public API.
|
||||
*
|
||||
@ -11,77 +11,75 @@
|
||||
#define __sslproto_h_
|
||||
|
||||
/* All versions less than 3_0 are treated as SSL version 2 */
|
||||
#define SSL_LIBRARY_VERSION_2 0x0002
|
||||
#define SSL_LIBRARY_VERSION_3_0 0x0300
|
||||
#define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
|
||||
#define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
|
||||
#define SSL_LIBRARY_VERSION_TLS_1_2 0x0303
|
||||
#define SSL_LIBRARY_VERSION_2 0x0002
|
||||
#define SSL_LIBRARY_VERSION_3_0 0x0300
|
||||
#define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
|
||||
#define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
|
||||
#define SSL_LIBRARY_VERSION_TLS_1_2 0x0303
|
||||
/* Note: this is the internal format, not the wire format */
|
||||
#define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302
|
||||
#define SSL_LIBRARY_VERSION_DTLS_1_2 0x0303
|
||||
#define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302
|
||||
|
||||
/* deprecated old name */
|
||||
#define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
|
||||
#define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
|
||||
|
||||
/* The DTLS versions used in the spec */
|
||||
/* The DTLS version used in the spec */
|
||||
#define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE ((~0x0100) & 0xffff)
|
||||
#define SSL_LIBRARY_VERSION_DTLS_1_2_WIRE ((~0x0102) & 0xffff)
|
||||
|
||||
/* Header lengths of some of the messages */
|
||||
#define SSL_HL_ERROR_HBYTES 3
|
||||
#define SSL_HL_CLIENT_HELLO_HBYTES 9
|
||||
#define SSL_HL_CLIENT_MASTER_KEY_HBYTES 10
|
||||
#define SSL_HL_CLIENT_FINISHED_HBYTES 1
|
||||
#define SSL_HL_SERVER_HELLO_HBYTES 11
|
||||
#define SSL_HL_SERVER_VERIFY_HBYTES 1
|
||||
#define SSL_HL_SERVER_FINISHED_HBYTES 1
|
||||
#define SSL_HL_REQUEST_CERTIFICATE_HBYTES 2
|
||||
#define SSL_HL_CLIENT_CERTIFICATE_HBYTES 6
|
||||
#define SSL_HL_ERROR_HBYTES 3
|
||||
#define SSL_HL_CLIENT_HELLO_HBYTES 9
|
||||
#define SSL_HL_CLIENT_MASTER_KEY_HBYTES 10
|
||||
#define SSL_HL_CLIENT_FINISHED_HBYTES 1
|
||||
#define SSL_HL_SERVER_HELLO_HBYTES 11
|
||||
#define SSL_HL_SERVER_VERIFY_HBYTES 1
|
||||
#define SSL_HL_SERVER_FINISHED_HBYTES 1
|
||||
#define SSL_HL_REQUEST_CERTIFICATE_HBYTES 2
|
||||
#define SSL_HL_CLIENT_CERTIFICATE_HBYTES 6
|
||||
|
||||
/* Security handshake protocol codes */
|
||||
#define SSL_MT_ERROR 0
|
||||
#define SSL_MT_CLIENT_HELLO 1
|
||||
#define SSL_MT_CLIENT_MASTER_KEY 2
|
||||
#define SSL_MT_CLIENT_FINISHED 3
|
||||
#define SSL_MT_SERVER_HELLO 4
|
||||
#define SSL_MT_SERVER_VERIFY 5
|
||||
#define SSL_MT_SERVER_FINISHED 6
|
||||
#define SSL_MT_REQUEST_CERTIFICATE 7
|
||||
#define SSL_MT_CLIENT_CERTIFICATE 8
|
||||
#define SSL_MT_ERROR 0
|
||||
#define SSL_MT_CLIENT_HELLO 1
|
||||
#define SSL_MT_CLIENT_MASTER_KEY 2
|
||||
#define SSL_MT_CLIENT_FINISHED 3
|
||||
#define SSL_MT_SERVER_HELLO 4
|
||||
#define SSL_MT_SERVER_VERIFY 5
|
||||
#define SSL_MT_SERVER_FINISHED 6
|
||||
#define SSL_MT_REQUEST_CERTIFICATE 7
|
||||
#define SSL_MT_CLIENT_CERTIFICATE 8
|
||||
|
||||
/* Certificate types */
|
||||
#define SSL_CT_X509_CERTIFICATE 0x01
|
||||
#define SSL_CT_X509_CERTIFICATE 0x01
|
||||
#if 0 /* XXX Not implemented yet */
|
||||
#define SSL_PKCS6_CERTIFICATE 0x02
|
||||
#define SSL_PKCS6_CERTIFICATE 0x02
|
||||
#endif
|
||||
#define SSL_AT_MD5_WITH_RSA_ENCRYPTION 0x01
|
||||
#define SSL_AT_MD5_WITH_RSA_ENCRYPTION 0x01
|
||||
|
||||
/* Error codes */
|
||||
#define SSL_PE_NO_CYPHERS 0x0001
|
||||
#define SSL_PE_NO_CERTIFICATE 0x0002
|
||||
#define SSL_PE_BAD_CERTIFICATE 0x0004
|
||||
#define SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
|
||||
#define SSL_PE_NO_CYPHERS 0x0001
|
||||
#define SSL_PE_NO_CERTIFICATE 0x0002
|
||||
#define SSL_PE_BAD_CERTIFICATE 0x0004
|
||||
#define SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
|
||||
|
||||
/* Cypher kinds (not the spec version!) */
|
||||
#define SSL_CK_RC4_128_WITH_MD5 0x01
|
||||
#define SSL_CK_RC4_128_EXPORT40_WITH_MD5 0x02
|
||||
#define SSL_CK_RC2_128_CBC_WITH_MD5 0x03
|
||||
#define SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x04
|
||||
#define SSL_CK_IDEA_128_CBC_WITH_MD5 0x05
|
||||
#define SSL_CK_DES_64_CBC_WITH_MD5 0x06
|
||||
#define SSL_CK_DES_192_EDE3_CBC_WITH_MD5 0x07
|
||||
#define SSL_CK_RC4_128_WITH_MD5 0x01
|
||||
#define SSL_CK_RC4_128_EXPORT40_WITH_MD5 0x02
|
||||
#define SSL_CK_RC2_128_CBC_WITH_MD5 0x03
|
||||
#define SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x04
|
||||
#define SSL_CK_IDEA_128_CBC_WITH_MD5 0x05
|
||||
#define SSL_CK_DES_64_CBC_WITH_MD5 0x06
|
||||
#define SSL_CK_DES_192_EDE3_CBC_WITH_MD5 0x07
|
||||
|
||||
/* Cipher enables. These are used only for SSL_EnableCipher
|
||||
* These values define the SSL2 suites, and do not colide with the
|
||||
/* Cipher enables. These are used only for SSL_EnableCipher
|
||||
* These values define the SSL2 suites, and do not colide with the
|
||||
* SSL3 Cipher suites defined below.
|
||||
*/
|
||||
#define SSL_EN_RC4_128_WITH_MD5 0xFF01
|
||||
#define SSL_EN_RC4_128_EXPORT40_WITH_MD5 0xFF02
|
||||
#define SSL_EN_RC2_128_CBC_WITH_MD5 0xFF03
|
||||
#define SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 0xFF04
|
||||
#define SSL_EN_IDEA_128_CBC_WITH_MD5 0xFF05
|
||||
#define SSL_EN_DES_64_CBC_WITH_MD5 0xFF06
|
||||
#define SSL_EN_DES_192_EDE3_CBC_WITH_MD5 0xFF07
|
||||
#define SSL_EN_RC4_128_WITH_MD5 0xFF01
|
||||
#define SSL_EN_RC4_128_EXPORT40_WITH_MD5 0xFF02
|
||||
#define SSL_EN_RC2_128_CBC_WITH_MD5 0xFF03
|
||||
#define SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 0xFF04
|
||||
#define SSL_EN_IDEA_128_CBC_WITH_MD5 0xFF05
|
||||
#define SSL_EN_DES_64_CBC_WITH_MD5 0xFF06
|
||||
#define SSL_EN_DES_192_EDE3_CBC_WITH_MD5 0xFF07
|
||||
|
||||
/* Deprecated SSL 3.0 & libssl names replaced by IANA-registered TLS names. */
|
||||
#ifndef SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES
|
||||
@ -119,66 +117,66 @@
|
||||
#define TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
|
||||
#endif
|
||||
|
||||
#define TLS_NULL_WITH_NULL_NULL 0x0000
|
||||
#define TLS_NULL_WITH_NULL_NULL 0x0000
|
||||
|
||||
#define TLS_RSA_WITH_NULL_MD5 0x0001
|
||||
#define TLS_RSA_WITH_NULL_SHA 0x0002
|
||||
#define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
|
||||
#define TLS_RSA_WITH_RC4_128_MD5 0x0004
|
||||
#define TLS_RSA_WITH_RC4_128_SHA 0x0005
|
||||
#define TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006
|
||||
#define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007
|
||||
#define TLS_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008
|
||||
#define TLS_RSA_WITH_DES_CBC_SHA 0x0009
|
||||
#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000a
|
||||
#define TLS_RSA_WITH_NULL_MD5 0x0001
|
||||
#define TLS_RSA_WITH_NULL_SHA 0x0002
|
||||
#define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
|
||||
#define TLS_RSA_WITH_RC4_128_MD5 0x0004
|
||||
#define TLS_RSA_WITH_RC4_128_SHA 0x0005
|
||||
#define TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006
|
||||
#define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007
|
||||
#define TLS_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008
|
||||
#define TLS_RSA_WITH_DES_CBC_SHA 0x0009
|
||||
#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000a
|
||||
|
||||
#define TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000b
|
||||
#define TLS_DH_DSS_WITH_DES_CBC_SHA 0x000c
|
||||
#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000d
|
||||
#define TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000e
|
||||
#define TLS_DH_RSA_WITH_DES_CBC_SHA 0x000f
|
||||
#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010
|
||||
#define TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000b
|
||||
#define TLS_DH_DSS_WITH_DES_CBC_SHA 0x000c
|
||||
#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000d
|
||||
#define TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000e
|
||||
#define TLS_DH_RSA_WITH_DES_CBC_SHA 0x000f
|
||||
#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010
|
||||
|
||||
#define TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011
|
||||
#define TLS_DHE_DSS_WITH_DES_CBC_SHA 0x0012
|
||||
#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013
|
||||
#define TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014
|
||||
#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x0015
|
||||
#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016
|
||||
#define TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011
|
||||
#define TLS_DHE_DSS_WITH_DES_CBC_SHA 0x0012
|
||||
#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013
|
||||
#define TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014
|
||||
#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x0015
|
||||
#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016
|
||||
|
||||
#define TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 0x0017
|
||||
#define TLS_DH_anon_WITH_RC4_128_MD5 0x0018
|
||||
#define TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA 0x0019
|
||||
#define TLS_DH_anon_WITH_DES_CBC_SHA 0x001a
|
||||
#define TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001b
|
||||
#define TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 0x0017
|
||||
#define TLS_DH_anon_WITH_RC4_128_MD5 0x0018
|
||||
#define TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA 0x0019
|
||||
#define TLS_DH_anon_WITH_DES_CBC_SHA 0x001a
|
||||
#define TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001b
|
||||
|
||||
#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c /* deprecated */
|
||||
#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d /* deprecated */
|
||||
#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e /* deprecated */
|
||||
#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c /* deprecated */
|
||||
#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d /* deprecated */
|
||||
#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e /* deprecated */
|
||||
|
||||
#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F
|
||||
#define TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030
|
||||
#define TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031
|
||||
#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032
|
||||
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033
|
||||
#define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034
|
||||
#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F
|
||||
#define TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030
|
||||
#define TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031
|
||||
#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032
|
||||
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033
|
||||
#define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034
|
||||
|
||||
#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
|
||||
#define TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036
|
||||
#define TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037
|
||||
#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038
|
||||
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039
|
||||
#define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A
|
||||
#define TLS_RSA_WITH_NULL_SHA256 0x003B
|
||||
#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C
|
||||
#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D
|
||||
#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
|
||||
#define TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036
|
||||
#define TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037
|
||||
#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038
|
||||
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039
|
||||
#define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A
|
||||
#define TLS_RSA_WITH_NULL_SHA256 0x003B
|
||||
#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C
|
||||
#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D
|
||||
|
||||
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0041
|
||||
#define TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0042
|
||||
#define TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0043
|
||||
#define TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0044
|
||||
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0045
|
||||
#define TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA 0x0046
|
||||
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0041
|
||||
#define TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0042
|
||||
#define TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0043
|
||||
#define TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0044
|
||||
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0045
|
||||
#define TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA 0x0046
|
||||
|
||||
#define TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x0062
|
||||
#define TLS_RSA_EXPORT1024_WITH_RC4_56_SHA 0x0064
|
||||
@ -189,14 +187,14 @@
|
||||
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067
|
||||
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B
|
||||
|
||||
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0084
|
||||
#define TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x0085
|
||||
#define TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0086
|
||||
#define TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x0087
|
||||
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0088
|
||||
#define TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA 0x0089
|
||||
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0084
|
||||
#define TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x0085
|
||||
#define TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0086
|
||||
#define TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x0087
|
||||
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0088
|
||||
#define TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA 0x0089
|
||||
|
||||
#define TLS_RSA_WITH_SEED_CBC_SHA 0x0096
|
||||
#define TLS_RSA_WITH_SEED_CBC_SHA 0x0096
|
||||
|
||||
#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C
|
||||
#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E
|
||||
@ -206,7 +204,7 @@
|
||||
* Must NEVER be chosen by server. SSL 3.0 server acknowledges by sending
|
||||
* back an empty Renegotiation Info (RI) server hello extension.
|
||||
*/
|
||||
#define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF
|
||||
#define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF
|
||||
|
||||
/* Cipher Suite Values starting with 0xC000 are defined in informational
|
||||
* RFCs.
|
||||
@ -250,18 +248,18 @@
|
||||
#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031
|
||||
|
||||
/* Netscape "experimental" cipher suites. */
|
||||
#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
|
||||
#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
|
||||
#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
|
||||
#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
|
||||
|
||||
/* New non-experimental openly spec'ed versions of those cipher suites. */
|
||||
#define SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA 0xfeff
|
||||
#define SSL_RSA_FIPS_WITH_DES_CBC_SHA 0xfefe
|
||||
#define SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA 0xfeff
|
||||
#define SSL_RSA_FIPS_WITH_DES_CBC_SHA 0xfefe
|
||||
|
||||
/* DTLS-SRTP cipher suites from RFC 5764 */
|
||||
/* If you modify this, also modify MAX_DTLS_SRTP_CIPHER_SUITES in sslimpl.h */
|
||||
#define SRTP_AES128_CM_HMAC_SHA1_80 0x0001
|
||||
#define SRTP_AES128_CM_HMAC_SHA1_32 0x0002
|
||||
#define SRTP_NULL_HMAC_SHA1_80 0x0005
|
||||
#define SRTP_NULL_HMAC_SHA1_32 0x0006
|
||||
#define SRTP_AES128_CM_HMAC_SHA1_80 0x0001
|
||||
#define SRTP_AES128_CM_HMAC_SHA1_32 0x0002
|
||||
#define SRTP_NULL_HMAC_SHA1_80 0x0005
|
||||
#define SRTP_NULL_HMAC_SHA1_32 0x0006
|
||||
|
||||
#endif /* __sslproto_h_ */
|
||||
|
@ -1370,11 +1370,6 @@ DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
|
||||
return ssl_ImportFD(model, fd, ssl_variant_datagram);
|
||||
}
|
||||
|
||||
/* SSL_SetNextProtoCallback is used to select an application protocol
|
||||
* for ALPN and NPN. For ALPN, this runs on the server; for NPN it
|
||||
* runs on the client. */
|
||||
/* Note: The ALPN version doesn't allow for the use of a default, setting a
|
||||
* status of SSL_NEXT_PROTO_NO_OVERLAP is treated as a failure. */
|
||||
SECStatus
|
||||
SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
|
||||
void *arg)
|
||||
@ -1395,7 +1390,7 @@ SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* ssl_NextProtoNegoCallback is set as an ALPN/NPN callback when
|
||||
/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when
|
||||
* SSL_SetNextProtoNego is used.
|
||||
*/
|
||||
static SECStatus
|
||||
@ -1414,6 +1409,12 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (protos_len == 0) {
|
||||
/* The server supports the extension, but doesn't have any protocols
|
||||
* configured. In this case we request our favoured protocol. */
|
||||
goto pick_first;
|
||||
}
|
||||
|
||||
/* For each protocol in server preference, see if we support it. */
|
||||
for (i = 0; i < protos_len; ) {
|
||||
for (j = 0; j < ss->opt.nextProtoNego.len; ) {
|
||||
@ -1430,10 +1431,7 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
|
||||
i += 1 + (unsigned int)protos[i];
|
||||
}
|
||||
|
||||
/* The other side supports the extension, and either doesn't have any
|
||||
* protocols configured, or none of its options match ours. In this case we
|
||||
* request our favoured protocol. */
|
||||
/* This will be treated as a failure for ALPN. */
|
||||
pick_first:
|
||||
ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
|
||||
result = ss->opt.nextProtoNego.data;
|
||||
|
||||
|
@ -1176,201 +1176,6 @@ cert_extensions()
|
||||
done < ${QADIR}/cert/certext.txt
|
||||
}
|
||||
|
||||
cert_make_with_param()
|
||||
{
|
||||
DIRPASS="$1"
|
||||
CERTNAME="$2"
|
||||
MAKE="$3"
|
||||
SUBJ="$4"
|
||||
EXTRA="$5"
|
||||
EXPECT="$6"
|
||||
TESTNAME="$7"
|
||||
|
||||
echo certutil ${DIRPASS} -s "${SUBJ}" ${MAKE} ${CERTNAME} ${EXTRA}
|
||||
${BINDIR}/certutil ${DIRPASS} -s "${SUBJ}" ${MAKE} ${CERTNAME} ${EXTRA}
|
||||
|
||||
RET=$?
|
||||
if [ "${RET}" -ne "${EXPECT}" ]; then
|
||||
# if we expected failure to create, then delete unexpected certificate
|
||||
if [ "${EXPECT}" -ne 0 ]; then
|
||||
${BINDIR}/certutil ${DIRPASS} -D ${CERTNAME}
|
||||
fi
|
||||
|
||||
CERTFAILED=1
|
||||
html_failed "${TESTNAME} (${COUNT}) - ${EXTRA}"
|
||||
cert_log "ERROR: ${TESTNAME} - ${EXTRA} failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
html_passed "${TESTNAME} (${COUNT})"
|
||||
return 0
|
||||
}
|
||||
|
||||
cert_list_and_count_dns()
|
||||
{
|
||||
DIRPASS="$1"
|
||||
CERTNAME="$2"
|
||||
EXPECT="$3"
|
||||
EXPECTCOUNT="$4"
|
||||
TESTNAME="$5"
|
||||
|
||||
echo certutil ${DIRPASS} -L ${CERTNAME}
|
||||
${BINDIR}/certutil ${DIRPASS} -L ${CERTNAME}
|
||||
|
||||
RET=$?
|
||||
if [ "${RET}" -ne "${EXPECT}" ]; then
|
||||
CERTFAILED=1
|
||||
html_failed "${TESTNAME} (${COUNT}) - list and count"
|
||||
cert_log "ERROR: ${TESTNAME} - list and count failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
LISTCOUNT=`${BINDIR}/certutil ${DIRPASS} -L ${CERTNAME} | grep -wc DNS`
|
||||
if [ "${LISTCOUNT}" -ne "${EXPECTCOUNT}" ]; then
|
||||
CERTFAILED=1
|
||||
html_failed "${TESTNAME} (${COUNT}) - list and count"
|
||||
cert_log "ERROR: ${TESTNAME} - list and count failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
html_passed "${TESTNAME} (${COUNT})"
|
||||
return 0
|
||||
}
|
||||
|
||||
cert_dump_ext_to_file()
|
||||
{
|
||||
DIRPASS="$1"
|
||||
CERTNAME="$2"
|
||||
OID="$3"
|
||||
OUTFILE="$4"
|
||||
EXPECT="$5"
|
||||
TESTNAME="$6"
|
||||
|
||||
echo certutil ${DIRPASS} -L ${CERTNAME} --dump-ext-val ${OID}
|
||||
echo "writing output to ${OUTFILE}"
|
||||
${BINDIR}/certutil ${DIRPASS} -L ${CERTNAME} --dump-ext-val ${OID} > ${OUTFILE}
|
||||
|
||||
RET=$?
|
||||
if [ "${RET}" -ne "${EXPECT}" ]; then
|
||||
CERTFAILED=1
|
||||
html_failed "${TESTNAME} (${COUNT}) - dump to file"
|
||||
cert_log "ERROR: ${TESTNAME} - dump to file failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
html_passed "${TESTNAME} (${COUNT})"
|
||||
return 0
|
||||
}
|
||||
|
||||
cert_delete()
|
||||
{
|
||||
DIRPASS="$1"
|
||||
CERTNAME="$2"
|
||||
EXPECT="$3"
|
||||
TESTNAME="$4"
|
||||
|
||||
echo certutil ${DIRPASS} -D ${CERTNAME}
|
||||
${BINDIR}/certutil ${DIRPASS} -D ${CERTNAME}
|
||||
|
||||
RET=$?
|
||||
if [ "${RET}" -ne "${EXPECT}" ]; then
|
||||
CERTFAILED=1
|
||||
html_failed "${TESTNAME} (${COUNT}) - delete cert"
|
||||
cert_log "ERROR: ${TESTNAME} - delete cert failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
html_passed "${TESTNAME} (${COUNT})"
|
||||
return 0
|
||||
}
|
||||
|
||||
cert_inc_count()
|
||||
{
|
||||
COUNT=`expr ${COUNT} + 1`
|
||||
}
|
||||
|
||||
############################## cert_crl_ssl ############################
|
||||
# test adding subject-alt-name, dumping, and adding generic extension
|
||||
########################################################################
|
||||
cert_san_and_generic_extensions()
|
||||
{
|
||||
EXTDUMP=${CERT_EXTENSIONS_DIR}/sanext.der
|
||||
|
||||
DIR="-d ${CERT_EXTENSIONS_DIR} -f ${R_PWFILE}"
|
||||
CERTNAME="-n WithSAN"
|
||||
MAKE="-S -t ,, -x -z ${R_NOISE_FILE}"
|
||||
SUBJ="CN=example.com"
|
||||
|
||||
TESTNAME="san-and-generic-extensions"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extSAN example.com" 255 \
|
||||
"create cert with invalid SAN parameter"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extSAN example.com,dns:www.example.com" 255 \
|
||||
"create cert with invalid SAN parameter"
|
||||
|
||||
TN="create cert with valid SAN parameter"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extSAN dns:example.com,dns:www.example.com" 0 \
|
||||
"${TN}"
|
||||
|
||||
cert_inc_count
|
||||
cert_list_and_count_dns "${DIR}" "${CERTNAME}" 0 2 \
|
||||
"${TN}"
|
||||
|
||||
cert_inc_count
|
||||
cert_dump_ext_to_file "${DIR}" "${CERTNAME}" "2.5.29.17" "${EXTDUMP}" 0 \
|
||||
"dump extension 2.5.29.17 to file ${EXTDUMP}"
|
||||
|
||||
cert_inc_count
|
||||
cert_delete "${DIR}" "${CERTNAME}" 0 \
|
||||
"${TN}"
|
||||
|
||||
cert_inc_count
|
||||
cert_list_and_count_dns "${DIR}" "${CERTNAME}" 255 0 \
|
||||
"expect failure to list cert, because we deleted it"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extGeneric ${EXTDUMP}" 255 \
|
||||
"create cert with invalid generic ext parameter"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extGeneric not-critical:${EXTDUMP}" 255 \
|
||||
"create cert with invalid generic ext parameter"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extGeneric not-critical:${EXTDUMP},2.5.29.17:critical:${EXTDUMP}" 255 \
|
||||
"create cert with invalid generic ext parameter"
|
||||
|
||||
TN="create cert with valid generic ext parameter"
|
||||
|
||||
cert_inc_count
|
||||
cert_make_with_param "${DIR}" "${CERTNAME}" "${MAKE}" "${SUBJ}" \
|
||||
"--extGeneric 2.5.29.17:not-critical:${EXTDUMP}" 0 \
|
||||
"${TN}"
|
||||
|
||||
cert_inc_count
|
||||
cert_list_and_count_dns "${DIR}" "${CERTNAME}" 0 2 \
|
||||
"${TN}"
|
||||
|
||||
cert_inc_count
|
||||
cert_delete "${DIR}" "${CERTNAME}" 0 \
|
||||
"${TN}"
|
||||
|
||||
cert_inc_count
|
||||
cert_list_and_count_dns "${DIR}" "${CERTNAME}" 255 0 \
|
||||
"expect failure to list cert, because we deleted it"
|
||||
}
|
||||
|
||||
############################## cert_crl_ssl ############################
|
||||
# local shell function to generate certs and crls for SSL tests
|
||||
########################################################################
|
||||
@ -1708,7 +1513,6 @@ if [ -z "$NSS_TEST_DISABLE_FIPS" ]; then
|
||||
fi
|
||||
cert_eccurves
|
||||
cert_extensions
|
||||
cert_san_and_generic_extensions
|
||||
cert_test_password
|
||||
cert_test_distrust
|
||||
cert_test_ocspresp
|
||||
|
Loading…
Reference in New Issue
Block a user