diff options
Diffstat (limited to 'security/nss/cmd/certutil/certext.c')
-rw-r--r-- | security/nss/cmd/certutil/certext.c | 321 |
1 files changed, 222 insertions, 99 deletions
diff --git a/security/nss/cmd/certutil/certext.c b/security/nss/cmd/certutil/certext.c index cdebedc6b..ee7b00ddc 100644 --- a/security/nss/cmd/certutil/certext.c +++ b/security/nss/cmd/certutil/certext.c @@ -278,49 +278,121 @@ GetYesNo(char *prompt) return (buffPrt && (buf[0] == 'y' || buf[0] == 'Y')) ? PR_TRUE : PR_FALSE; } +/* Parses comma separated values out of the string pointed by nextPos. + * Parsed value is compared to an array of possible values(valueArray). + * If match is found, a value index is returned, otherwise returns SECFailue. + * nextPos is set to the token after found comma separator or to NULL. + * NULL in nextPos should be used as indication of the last parsed token. + * A special value "critical" can be parsed out from the supplied sting.*/ + +static SECStatus +parseNextCmdInput(const char * const *valueArray, int *value, char **nextPos, + PRBool *critical) +{ + char *thisPos = *nextPos; + int keyLen = 0; + int arrIndex = 0; + + if (!valueArray || !value || !nextPos || !critical) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + while (1) { + if ((*nextPos = strchr(thisPos, ',')) == NULL) { + keyLen = strlen(thisPos); + } else { + keyLen = *nextPos - thisPos; + *nextPos += 1; + } + /* if critical keyword is found, go for another loop, + * but check, if it is the last keyword of + * the string.*/ + if (!strncmp("critical", thisPos, keyLen)) { + *critical = PR_TRUE; + if (*nextPos == NULL) { + return SECSuccess; + } + thisPos = *nextPos; + continue; + } + break; + } + for (arrIndex = 0; valueArray[arrIndex]; arrIndex++) { + if (!strncmp(valueArray[arrIndex], thisPos, keyLen)) { + *value = arrIndex; + return SECSuccess; + } + } + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +} + +static const char * const +keyUsageKeyWordArray[] = { "digitalSignature", + "nonRepudiation", + "keyEncipherment", + "dataEncipherment", + "keyAgreement", + "certSigning", + "crlSigning", + NULL}; + static SECStatus -AddKeyUsage (void *extHandle) +AddKeyUsage (void *extHandle, const char *userSuppliedValue) { SECItem bitStringValue; unsigned char keyUsage = 0x0; char buffer[5]; int value; - PRBool yesNoAns; - - while (1) { - if (PrintChoicesAndGetAnswer( - "\t\t0 - Digital Signature\n" - "\t\t1 - Non-repudiation\n" - "\t\t2 - Key encipherment\n" - "\t\t3 - Data encipherment\n" - "\t\t4 - Key agreement\n" - "\t\t5 - Cert signing key\n" - "\t\t6 - CRL signing key\n" - "\t\tOther to finish\n", - buffer, sizeof(buffer)) == SECFailure) { - return SECFailure; + char *nextPos = (char*)userSuppliedValue; + PRBool isCriticalExt = PR_FALSE; + + if (!userSuppliedValue) { + while (1) { + if (PrintChoicesAndGetAnswer( + "\t\t0 - Digital Signature\n" + "\t\t1 - Non-repudiation\n" + "\t\t2 - Key encipherment\n" + "\t\t3 - Data encipherment\n" + "\t\t4 - Key agreement\n" + "\t\t5 - Cert signing key\n" + "\t\t6 - CRL signing key\n" + "\t\tOther to finish\n", + buffer, sizeof(buffer)) == SECFailure) { + return SECFailure; + } + value = PORT_Atoi (buffer); + if (value < 0 || value > 6) + break; + if (value == 0) { + /* Checking that zero value of variable 'value' + * corresponds to '0' input made by user */ + char *chPtr = strchr(buffer, '0'); + if (chPtr == NULL) { + continue; + } + } + keyUsage |= (0x80 >> value); } - value = PORT_Atoi (buffer); - if (value < 0 || value > 6) - break; - if (value == 0) { - /* Checking that zero value of variable 'value' - * corresponds to '0' input made by user */ - char *chPtr = strchr(buffer, '0'); - if (chPtr == NULL) { - continue; + isCriticalExt = GetYesNo("Is this a critical extension [y/N]?"); + } else { + while (1) { + if (parseNextCmdInput(keyUsageKeyWordArray, &value, &nextPos, + &isCriticalExt) == SECFailure) { + return SECFailure; } + keyUsage |= (0x80 >> value); + if (!nextPos) + break; } - keyUsage |= (0x80 >> value); } bitStringValue.data = &keyUsage; bitStringValue.len = 1; - yesNoAns = GetYesNo("Is this a critical extension [y/N]?"); return (CERT_EncodeAndAddBitStrExtension (extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue, - yesNoAns)); + isCriticalExt)); } @@ -378,6 +450,10 @@ AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag) } for( oids = os->oids; (SECItem *)NULL != *oids; oids++ ) { + if (*oids == &od->oid) { + /* We already have this oid */ + return SECSuccess; + } count++; } @@ -432,42 +508,60 @@ loser: return (SECItem *)NULL; } +static const char * const +extKeyUsageKeyWordArray[] = { "serverAuth", + "clientAuth", + "codeSigning", + "emailProtection", + "timeStamp", + "ocspResponder", + "stepUp", + NULL}; + static SECStatus -AddExtKeyUsage (void *extHandle) +AddExtKeyUsage (void *extHandle, const char *userSuppliedValue) { char buffer[5]; int value; CERTOidSequence *os; SECStatus rv; SECItem *item; - PRBool yesNoAns; - + PRBool isCriticalExt = PR_FALSE; + char *nextPos = (char*)userSuppliedValue; + os = CreateOidSequence(); if( (CERTOidSequence *)NULL == os ) { return SECFailure; } while (1) { - if (PrintChoicesAndGetAnswer( - "\t\t0 - Server Auth\n" - "\t\t1 - Client Auth\n" - "\t\t2 - Code Signing\n" - "\t\t3 - Email Protection\n" - "\t\t4 - Timestamp\n" - "\t\t5 - OCSP Responder\n" - "\t\t6 - Step-up\n" - "\t\tOther to finish\n", - buffer, sizeof(buffer)) == SECFailure) { - GEN_BREAK(SECFailure); - } - value = PORT_Atoi(buffer); - - if (value == 0) { - /* Checking that zero value of variable 'value' - * corresponds to '0' input made by user */ - char *chPtr = strchr(buffer, '0'); - if (chPtr == NULL) { - continue; + if (!userSuppliedValue) { + if (PrintChoicesAndGetAnswer( + "\t\t0 - Server Auth\n" + "\t\t1 - Client Auth\n" + "\t\t2 - Code Signing\n" + "\t\t3 - Email Protection\n" + "\t\t4 - Timestamp\n" + "\t\t5 - OCSP Responder\n" + "\t\t6 - Step-up\n" + "\t\tOther to finish\n", + buffer, sizeof(buffer)) == SECFailure) { + GEN_BREAK(SECFailure); + } + value = PORT_Atoi(buffer); + + if (value == 0) { + /* Checking that zero value of variable 'value' + * corresponds to '0' input made by user */ + char *chPtr = strchr(buffer, '0'); + if (chPtr == NULL) { + continue; + } + } + } else { + if (parseNextCmdInput(extKeyUsageKeyWordArray, &value, &nextPos, + &isCriticalExt) == SECFailure) { + return SECFailure; } } @@ -497,66 +591,95 @@ AddExtKeyUsage (void *extHandle) goto endloop; } - if( SECSuccess != rv ) goto loser; + if (userSuppliedValue && !nextPos) + break; + if( SECSuccess != rv ) + goto loser; } endloop: item = EncodeOidSequence(os); - yesNoAns = GetYesNo("Is this a critical extension [y/N]?"); + if (!userSuppliedValue) { + isCriticalExt = GetYesNo("Is this a critical extension [y/N]?"); + } rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, item, - yesNoAns, PR_TRUE); + isCriticalExt, PR_TRUE); /*FALLTHROUGH*/ loser: DestroyOidSequence(os); return rv; } +static const char * const +nsCertTypeKeyWordArray[] = { "sslClient", + "sslServer", + "smime", + "objectSigning", + "Not!Used", + "sslCA", + "smimeCA", + "objectSigningCA", + NULL }; + static SECStatus -AddNscpCertType (void *extHandle) +AddNscpCertType (void *extHandle, const char *userSuppliedValue) { SECItem bitStringValue; unsigned char keyUsage = 0x0; char buffer[5]; int value; - PRBool yesNoAns; - - while (1) { - if (PrintChoicesAndGetAnswer( - "\t\t0 - SSL Client\n" - "\t\t1 - SSL Server\n" - "\t\t2 - S/MIME\n" - "\t\t3 - Object Signing\n" - "\t\t4 - Reserved for future use\n" - "\t\t5 - SSL CA\n" - "\t\t6 - S/MIME CA\n" - "\t\t7 - Object Signing CA\n" - "\t\tOther to finish\n", - buffer, sizeof(buffer)) == SECFailure) { - return SECFailure; + char *nextPos = (char*)userSuppliedValue; + PRBool isCriticalExt = PR_FALSE; + + if (!userSuppliedValue) { + while (1) { + if (PrintChoicesAndGetAnswer( + "\t\t0 - SSL Client\n" + "\t\t1 - SSL Server\n" + "\t\t2 - S/MIME\n" + "\t\t3 - Object Signing\n" + "\t\t4 - Reserved for future use\n" + "\t\t5 - SSL CA\n" + "\t\t6 - S/MIME CA\n" + "\t\t7 - Object Signing CA\n" + "\t\tOther to finish\n", + buffer, sizeof(buffer)) == SECFailure) { + return SECFailure; + } + value = PORT_Atoi (buffer); + if (value < 0 || value > 7) + break; + if (value == 0) { + /* Checking that zero value of variable 'value' + * corresponds to '0' input made by user */ + char *chPtr = strchr(buffer, '0'); + if (chPtr == NULL) { + continue; + } + } + keyUsage |= (0x80 >> value); } - value = PORT_Atoi (buffer); - if (value < 0 || value > 7) - break; - if (value == 0) { - /* Checking that zero value of variable 'value' - * corresponds to '0' input made by user */ - char *chPtr = strchr(buffer, '0'); - if (chPtr == NULL) { - continue; + isCriticalExt = GetYesNo("Is this a critical extension [y/N]?"); + } else { + while (1) { + if (parseNextCmdInput(nsCertTypeKeyWordArray, &value, &nextPos, + &isCriticalExt) == SECFailure) { + return SECFailure; } + keyUsage |= (0x80 >> value); + if (!nextPos) + break; } - keyUsage |= (0x80 >> value); } bitStringValue.data = &keyUsage; bitStringValue.len = 1; - yesNoAns = GetYesNo("Is this a critical extension [y/N]?"); return (CERT_EncodeAndAddBitStrExtension (extHandle, SEC_OID_NS_CERT_EXT_CERT_TYPE, &bitStringValue, - yesNoAns)); + isCriticalExt)); } @@ -571,7 +694,6 @@ AddSubjectAltNames(PRArenaPool *arena, CERTGeneralName **existingListp, char *tbuf; SECStatus rv = SECSuccess; - /* * walk down the comma separated list of names. NOTE: there is * no sanity checks to see if the email address look like @@ -1557,8 +1679,8 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, do { /* Add key usage extension */ - if (extList[ext_keyUsage]) { - rv = AddKeyUsage(extHandle); + if (extList[ext_keyUsage].activated) { + rv = AddKeyUsage(extHandle, extList[ext_keyUsage].arg); if (rv) { errstring = "KeyUsage"; break; @@ -1566,8 +1688,8 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } /* Add extended key usage extension */ - if (extList[ext_extKeyUsage]) { - rv = AddExtKeyUsage(extHandle); + if (extList[ext_extKeyUsage].activated) { + rv = AddExtKeyUsage(extHandle, extList[ext_extKeyUsage].arg); if (rv) { errstring = "ExtendedKeyUsage"; break; @@ -1575,7 +1697,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } /* Add basic constraint extension */ - if (extList[ext_basicConstraint]) { + if (extList[ext_basicConstraint].activated) { rv = AddBasicConstraint(extHandle); if (rv) { errstring = "BasicConstraint"; @@ -1583,7 +1705,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_authorityKeyID]) { + if (extList[ext_authorityKeyID].activated) { rv = AddAuthKeyID(extHandle); if (rv) { errstring = "AuthorityKeyID"; @@ -1591,7 +1713,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_subjectKeyID]) { + if (extList[ext_subjectKeyID].activated) { rv = AddSubjKeyID(extHandle); if (rv) { errstring = "SubjectKeyID"; @@ -1599,7 +1721,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_CRLDistPts]) { + if (extList[ext_CRLDistPts].activated) { rv = AddCrlDistPoint(extHandle); if (rv) { errstring = "CRLDistPoints"; @@ -1607,24 +1729,25 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_NSCertType]) { - rv = AddNscpCertType(extHandle); + if (extList[ext_NSCertType].activated) { + rv = AddNscpCertType(extHandle, extList[ext_extKeyUsage].arg); if (rv) { errstring = "NSCertType"; break; } } - if (extList[ext_authInfoAcc] || extList[ext_subjInfoAcc]) { - rv = AddInfoAccess(extHandle, extList[ext_subjInfoAcc], - extList[ext_basicConstraint]); + if (extList[ext_authInfoAcc].activated || + extList[ext_subjInfoAcc].activated) { + rv = AddInfoAccess(extHandle, extList[ext_subjInfoAcc].activated, + extList[ext_basicConstraint].activated); if (rv) { errstring = "InformationAccess"; break; } } - if (extList[ext_certPolicies]) { + if (extList[ext_certPolicies].activated) { rv = AddCertPolicies(extHandle); if (rv) { errstring = "Policies"; @@ -1632,7 +1755,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_policyMappings]) { + if (extList[ext_policyMappings].activated) { rv = AddPolicyMappings(extHandle); if (rv) { errstring = "PolicyMappings"; @@ -1640,7 +1763,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_policyConstr]) { + if (extList[ext_policyConstr].activated) { rv = AddPolicyConstraints(extHandle); if (rv) { errstring = "PolicyConstraints"; @@ -1648,7 +1771,7 @@ AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames, } } - if (extList[ext_inhibitAnyPolicy]) { + if (extList[ext_inhibitAnyPolicy].activated) { rv = AddInhibitAnyPolicy(extHandle); if (rv) { errstring = "InhibitAnyPolicy"; |