summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamilo Viecco <cviecco@mozilla.com>2014-02-27 15:25:12 -0800
committerCamilo Viecco <cviecco@mozilla.com>2014-02-27 15:25:12 -0800
commit33263f7d9f9c967098ebdaa1f8533e275a4a6879 (patch)
tree6998f12b1a59d0d5afad6af05436bd9a15e2438b
parenta7bbcec79239f18acad5f39a36333be47a35b3b1 (diff)
downloadnss-hg-33263f7d9f9c967098ebdaa1f8533e275a4a6879.tar.gz
Bug 976111: Allow certutil to generate v2, v3, and v4 certificates, r=briansmith
-rw-r--r--cmd/certutil/certutil.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/cmd/certutil/certutil.c b/cmd/certutil/certutil.c
index c81569330..a28851282 100644
--- a/cmd/certutil/certutil.c
+++ b/cmd/certutil/certutil.c
@@ -1736,7 +1736,8 @@ MakeV1Cert( CERTCertDBHandle * handle,
static SECStatus
SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign,
SECOidTag hashAlgTag,
- SECKEYPrivateKey *privKey, char *issuerNickName, void *pwarg)
+ SECKEYPrivateKey *privKey, char *issuerNickName,
+ int certVersion, void *pwarg)
{
SECItem der;
SECKEYPrivateKey *caPrivateKey = NULL;
@@ -1776,9 +1777,23 @@ SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign,
goto done;
}
- /* we only deal with cert v3 here */
- *(cert->version.data) = 2;
- cert->version.len = 1;
+ switch(certVersion) {
+ case (SEC_CERTIFICATE_VERSION_1):
+ // The initial version for x509 certificates is version one
+ // and this default value must be an implicit DER encoding.
+ cert->version.data = NULL;
+ cert->version.len = 0;
+ break;
+ case (SEC_CERTIFICATE_VERSION_2):
+ case (SEC_CERTIFICATE_VERSION_3):
+ case 3: // unspecified format (would be version 4 certificate).
+ *(cert->version.data) = certVersion;
+ cert->version.len = 1;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
der.len = 0;
der.data = NULL;
@@ -1821,6 +1836,7 @@ CreateCert(
PRBool ascii,
PRBool selfsign,
certutilExtnList extnList,
+ int certVersion,
SECItem * certDER)
{
void * extHandle;
@@ -1880,7 +1896,8 @@ CreateCert(
}
rv = SignCert(handle, subjectCert, selfsign, hashAlgTag,
- *selfsignprivkey, issuerNickName, pwarg);
+ *selfsignprivkey, issuerNickName,
+ certVersion, pwarg);
if (rv != SECSuccess)
break;
@@ -2194,6 +2211,7 @@ enum certutilOpts {
opt_KeyOpFlagsOff,
opt_KeyAttrFlags,
opt_EmptyPassword,
+ opt_CertVersion,
opt_Help
};
@@ -2303,6 +2321,8 @@ secuCommandFlag options_init[] =
"keyAttrFlags"},
{ /* opt_EmptyPassword */ 0, PR_FALSE, 0, PR_FALSE,
"empty-password"},
+ { /* opt_CertVersion */ 0, PR_FALSE, 0, PR_FALSE,
+ "certVersion"},
};
#define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0]))
@@ -2341,6 +2361,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
int keysize = DEFAULT_KEY_BITS;
int publicExponent = 0x010001;
+ int certVersion = SEC_CERTIFICATE_VERSION_3;
unsigned int serialNumber = 0;
int warpmonths = 0;
int validityMonths = 3;
@@ -2569,6 +2590,19 @@ certutil_main(int argc, char **argv, PRBool initialize)
}
}
+ /* --certVersion */
+ if (certutil.options[opt_CertVersion].activated) {
+ certVersion = PORT_Atoi(certutil.options[opt_CertVersion].arg);
+ if (certVersion < 1 || certVersion > 4) {
+ PR_fprintf(PR_STDERR, "%s -certVersion: incorrect certificate version %d.",
+ progName, certVersion);
+ PR_fprintf(PR_STDERR, "Must be 1, 2, 3 or 4.\n");
+ return 255;
+ }
+ certVersion = certVersion - 1;
+ }
+
+
/* Check number of commands entered. */
commandsEntered = 0;
for (i=0; i< certutil.numCommands; i++) {
@@ -3225,6 +3259,7 @@ merge_fail:
certutil.commands[cmd_CreateNewCert].activated,
certutil.options[opt_SelfSign].activated,
certutil_extns,
+ certVersion,
&certDER);
if (rv)
goto shutdown;