Index: cmd/certutil/certutil.c |
=================================================================== |
--- a/cmd/certutil/certutil.c |
+++ b/cmd/certutil/certutil.c |
@@ -32,946 +32,890 @@ |
#include "secasn1.h" |
#include "cert.h" |
#include "cryptohi.h" |
#include "secoid.h" |
#include "certdb.h" |
#include "nss.h" |
#include "certutil.h" |
-#define MIN_KEY_BITS 512 |
+#define MIN_KEY_BITS 512 |
/* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */ |
-#define MAX_KEY_BITS 8192 |
-#define DEFAULT_KEY_BITS 1024 |
+#define MAX_KEY_BITS 8192 |
+#define DEFAULT_KEY_BITS 1024 |
-#define GEN_BREAK(e) rv=e; break; |
+#define GEN_BREAK(e) \ |
+ rv = e; \ |
+ break; |
char *progName; |
-static CERTCertificateRequest * |
-GetCertRequest(const SECItem *reqDER) |
-{ |
- CERTCertificateRequest *certReq = NULL; |
- CERTSignedData signedData; |
- PLArenaPool *arena = NULL; |
- SECStatus rv; |
+static CERTCertificateRequest *GetCertRequest(const SECItem *reqDER) { |
+ CERTCertificateRequest *certReq = NULL; |
+ CERTSignedData signedData; |
+ PLArenaPool *arena = NULL; |
+ SECStatus rv; |
- do { |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (arena == NULL) { |
- GEN_BREAK (SECFailure); |
- } |
- |
- certReq = (CERTCertificateRequest*) PORT_ArenaZAlloc |
- (arena, sizeof(CERTCertificateRequest)); |
- if (!certReq) { |
- GEN_BREAK(SECFailure); |
- } |
- certReq->arena = arena; |
+ do { |
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
+ if (arena == NULL) { |
+ GEN_BREAK(SECFailure); |
+ } |
- /* Since cert request is a signed data, must decode to get the inner |
- data |
- */ |
- PORT_Memset(&signedData, 0, sizeof(signedData)); |
- rv = SEC_ASN1DecodeItem(arena, &signedData, |
- SEC_ASN1_GET(CERT_SignedDataTemplate), reqDER); |
- if (rv) { |
- break; |
- } |
- rv = SEC_ASN1DecodeItem(arena, certReq, |
- SEC_ASN1_GET(CERT_CertificateRequestTemplate), &signedData.data); |
- if (rv) { |
- break; |
- } |
- rv = CERT_VerifySignedDataWithPublicKeyInfo(&signedData, |
- &certReq->subjectPublicKeyInfo, NULL /* wincx */); |
- } while (0); |
+ certReq = (CERTCertificateRequest *)PORT_ArenaZAlloc( |
+ arena, sizeof(CERTCertificateRequest)); |
+ if (!certReq) { |
+ GEN_BREAK(SECFailure); |
+ } |
+ certReq->arena = arena; |
- if (rv) { |
- SECU_PrintError(progName, "bad certificate request\n"); |
- if (arena) { |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- certReq = NULL; |
- } |
+ /* Since cert request is a signed data, must decode to get the inner |
+ data |
+ */ |
+ PORT_Memset(&signedData, 0, sizeof(signedData)); |
+ rv = SEC_ASN1DecodeItem(arena, &signedData, |
+ SEC_ASN1_GET(CERT_SignedDataTemplate), reqDER); |
+ if (rv) { |
+ break; |
+ } |
+ rv = SEC_ASN1DecodeItem(arena, certReq, |
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), |
+ &signedData.data); |
+ if (rv) { |
+ break; |
+ } |
+ rv = CERT_VerifySignedDataWithPublicKeyInfo( |
+ &signedData, &certReq->subjectPublicKeyInfo, NULL /* wincx */); |
+ } while (0); |
- return certReq; |
+ if (rv) { |
+ SECU_PrintError(progName, "bad certificate request\n"); |
+ if (arena) { |
+ PORT_FreeArena(arena, PR_FALSE); |
+ } |
+ certReq = NULL; |
+ } |
+ |
+ return certReq; |
} |
-static SECStatus |
-AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts, |
- const SECItem *certDER, PRBool emailcert, void *pwdata) |
-{ |
- CERTCertTrust *trust = NULL; |
- CERTCertificate *cert = NULL; |
- SECStatus rv; |
+static SECStatus AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, |
+ char *name, char *trusts, const SECItem *certDER, |
+ PRBool emailcert, void *pwdata) { |
+ CERTCertTrust *trust = NULL; |
+ CERTCertificate *cert = NULL; |
+ SECStatus rv; |
- do { |
- /* Read in an ASCII cert and return a CERTCertificate */ |
- cert = CERT_DecodeCertFromPackage((char *)certDER->data, certDER->len); |
- if (!cert) { |
- SECU_PrintError(progName, "could not decode certificate"); |
- GEN_BREAK(SECFailure); |
- } |
+ do { |
+ /* Read in an ASCII cert and return a CERTCertificate */ |
+ cert = CERT_DecodeCertFromPackage((char *)certDER->data, certDER->len); |
+ if (!cert) { |
+ SECU_PrintError(progName, "could not decode certificate"); |
+ GEN_BREAK(SECFailure); |
+ } |
- /* Create a cert trust */ |
- trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust)); |
- if (!trust) { |
- SECU_PrintError(progName, "unable to allocate cert trust"); |
- GEN_BREAK(SECFailure); |
- } |
+ /* Create a cert trust */ |
+ trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust)); |
+ if (!trust) { |
+ SECU_PrintError(progName, "unable to allocate cert trust"); |
+ GEN_BREAK(SECFailure); |
+ } |
- rv = CERT_DecodeTrustString(trust, trusts); |
- if (rv) { |
- SECU_PrintError(progName, "unable to decode trust string"); |
- GEN_BREAK(SECFailure); |
- } |
+ rv = CERT_DecodeTrustString(trust, trusts); |
+ if (rv) { |
+ SECU_PrintError(progName, "unable to decode trust string"); |
+ GEN_BREAK(SECFailure); |
+ } |
- rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE); |
- if (rv != SECSuccess) { |
- /* sigh, PK11_Import Cert and CERT_ChangeCertTrust should have |
- * been coded to take a password arg. */ |
- if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) { |
- rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, |
- "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- GEN_BREAK(SECFailure); |
- } |
- rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, |
- name, PR_FALSE); |
- } |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, |
- "could not add certificate to token or database"); |
- GEN_BREAK(SECFailure); |
- } |
- } |
+ rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE); |
+ if (rv != SECSuccess) { |
+ /* sigh, PK11_Import Cert and CERT_ChangeCertTrust should have |
+ * been coded to take a password arg. */ |
+ if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) { |
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ GEN_BREAK(SECFailure); |
+ } |
+ rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE); |
+ } |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, |
+ "could not add certificate to token or database"); |
+ GEN_BREAK(SECFailure); |
+ } |
+ } |
- rv = CERT_ChangeCertTrust(handle, cert, trust); |
- if (rv != SECSuccess) { |
- if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) { |
- rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, |
- "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- GEN_BREAK(SECFailure); |
- } |
- rv = CERT_ChangeCertTrust(handle, cert, trust); |
- } |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, |
- "could not change trust on certificate"); |
- GEN_BREAK(SECFailure); |
- } |
- } |
+ rv = CERT_ChangeCertTrust(handle, cert, trust); |
+ if (rv != SECSuccess) { |
+ if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) { |
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ GEN_BREAK(SECFailure); |
+ } |
+ rv = CERT_ChangeCertTrust(handle, cert, trust); |
+ } |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "could not change trust on certificate"); |
+ GEN_BREAK(SECFailure); |
+ } |
+ } |
- if ( emailcert ) { |
- CERT_SaveSMimeProfile(cert, NULL, pwdata); |
- } |
+ if (emailcert) { |
+ CERT_SaveSMimeProfile(cert, NULL, pwdata); |
+ } |
- } while (0); |
+ } while (0); |
- CERT_DestroyCertificate (cert); |
- PORT_Free(trust); |
+ CERT_DestroyCertificate(cert); |
+ PORT_Free(trust); |
- return rv; |
+ return rv; |
} |
-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, |
- /*out*/ SECItem *result) |
-{ |
- CERTSubjectPublicKeyInfo *spki; |
- CERTCertificateRequest *cr; |
- SECItem *encoding; |
- SECOidTag signAlgTag; |
- SECStatus rv; |
- PLArenaPool *arena; |
- void *extHandle; |
- SECItem signedReq = { siBuffer, NULL, 0 }; |
+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, |
+ /*out*/ SECItem *result) { |
+ CERTSubjectPublicKeyInfo *spki; |
+ CERTCertificateRequest *cr; |
+ SECItem *encoding; |
+ SECOidTag signAlgTag; |
+ SECStatus rv; |
+ PLArenaPool *arena; |
+ void *extHandle; |
+ SECItem signedReq = {siBuffer, NULL, 0}; |
- /* Create info about public key */ |
- spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); |
- if (!spki) { |
- SECU_PrintError(progName, "unable to create subject public key"); |
- return SECFailure; |
- } |
- |
- /* Generate certificate request */ |
- cr = CERT_CreateCertificateRequest(subject, spki, NULL); |
- SECKEY_DestroySubjectPublicKeyInfo(spki); |
- if (!cr) { |
- SECU_PrintError(progName, "unable to make certificate request"); |
- return SECFailure; |
+ /* Create info about public key */ |
+ spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); |
+ if (!spki) { |
+ SECU_PrintError(progName, "unable to create subject public key"); |
+ return SECFailure; |
+ } |
+ |
+ /* Generate certificate request */ |
+ cr = CERT_CreateCertificateRequest(subject, spki, NULL); |
+ SECKEY_DestroySubjectPublicKeyInfo(spki); |
+ if (!cr) { |
+ SECU_PrintError(progName, "unable to make certificate request"); |
+ return SECFailure; |
+ } |
+ |
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
+ if (!arena) { |
+ SECU_PrintError(progName, "out of memory"); |
+ return SECFailure; |
+ } |
+ |
+ extHandle = CERT_StartCertificateRequestAttributes(cr); |
+ if (extHandle == NULL) { |
+ PORT_FreeArena(arena, PR_FALSE); |
+ return SECFailure; |
+ } |
+ if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric) != |
+ SECSuccess) { |
+ PORT_FreeArena(arena, PR_FALSE); |
+ return SECFailure; |
+ } |
+ CERT_FinishExtensions(extHandle); |
+ CERT_FinishCertificateRequestAttributes(cr); |
+ |
+ /* Der encode the request */ |
+ encoding = SEC_ASN1EncodeItem(arena, NULL, cr, |
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate)); |
+ CERT_DestroyCertificateRequest(cr); |
+ if (encoding == NULL) { |
+ PORT_FreeArena(arena, PR_FALSE); |
+ SECU_PrintError(progName, "der encoding of request failed"); |
+ return SECFailure; |
+ } |
+ |
+ /* Sign the request */ |
+ signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); |
+ if (signAlgTag == SEC_OID_UNKNOWN) { |
+ PORT_FreeArena(arena, PR_FALSE); |
+ SECU_PrintError(progName, "unknown Key or Hash type"); |
+ return SECFailure; |
+ } |
+ |
+ rv = SEC_DerSignData(arena, &signedReq, encoding->data, encoding->len, privk, |
+ signAlgTag); |
+ if (rv) { |
+ PORT_FreeArena(arena, PR_FALSE); |
+ SECU_PrintError(progName, "signing of data failed"); |
+ return SECFailure; |
+ } |
+ |
+ /* Encode request in specified format */ |
+ if (ascii) { |
+ char *obuf; |
+ char *header, *name, *email, *org, *state, *country; |
+ |
+ obuf = BTOA_ConvertItemToAscii(&signedReq); |
+ if (!obuf) { |
+ goto oom; |
} |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if ( !arena ) { |
- SECU_PrintError(progName, "out of memory"); |
- return SECFailure; |
- } |
- |
- extHandle = CERT_StartCertificateRequestAttributes(cr); |
- if (extHandle == NULL) { |
- PORT_FreeArena (arena, PR_FALSE); |
- return SECFailure; |
- } |
- if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric) |
- != SECSuccess) { |
- PORT_FreeArena (arena, PR_FALSE); |
- return SECFailure; |
- } |
- CERT_FinishExtensions(extHandle); |
- CERT_FinishCertificateRequestAttributes(cr); |
- |
- /* Der encode the request */ |
- encoding = SEC_ASN1EncodeItem(arena, NULL, cr, |
- SEC_ASN1_GET(CERT_CertificateRequestTemplate)); |
- CERT_DestroyCertificateRequest(cr); |
- if (encoding == NULL) { |
- PORT_FreeArena (arena, PR_FALSE); |
- SECU_PrintError(progName, "der encoding of request failed"); |
- return SECFailure; |
+ name = CERT_GetCommonName(subject); |
+ if (!name) { |
+ name = PORT_Strdup("(not specified)"); |
} |
- /* Sign the request */ |
- signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); |
- if (signAlgTag == SEC_OID_UNKNOWN) { |
- PORT_FreeArena (arena, PR_FALSE); |
- SECU_PrintError(progName, "unknown Key or Hash type"); |
- return SECFailure; |
+ if (!phone) phone = strdup("(not specified)"); |
+ |
+ email = CERT_GetCertEmailAddress(subject); |
+ if (!email) email = PORT_Strdup("(not specified)"); |
+ |
+ org = CERT_GetOrgName(subject); |
+ if (!org) org = PORT_Strdup("(not specified)"); |
+ |
+ state = CERT_GetStateName(subject); |
+ if (!state) state = PORT_Strdup("(not specified)"); |
+ |
+ country = CERT_GetCountryName(subject); |
+ if (!country) country = PORT_Strdup("(not specified)"); |
+ |
+ header = PR_smprintf( |
+ "\nCertificate request generated by Netscape certutil\n" |
+ "Phone: %s\n\n" |
+ "Common Name: %s\n" |
+ "Email: %s\n" |
+ "Organization: %s\n" |
+ "State: %s\n" |
+ "Country: %s\n\n" |
+ "%s\n", |
+ phone, name, email, org, state, country, NS_CERTREQ_HEADER); |
+ |
+ PORT_Free(name); |
+ PORT_Free(email); |
+ PORT_Free(org); |
+ PORT_Free(state); |
+ PORT_Free(country); |
+ |
+ if (header) { |
+ char *trailer = PR_smprintf("\n%s\n", NS_CERTREQ_TRAILER); |
+ if (trailer) { |
+ PRUint32 headerLen = PL_strlen(header); |
+ PRUint32 obufLen = PL_strlen(obuf); |
+ PRUint32 trailerLen = PL_strlen(trailer); |
+ SECITEM_AllocItem(NULL, result, headerLen + obufLen + trailerLen); |
+ if (result->data) { |
+ PORT_Memcpy(result->data, header, headerLen); |
+ PORT_Memcpy(result->data + headerLen, obuf, obufLen); |
+ PORT_Memcpy(result->data + headerLen + obufLen, trailer, trailerLen); |
+ } |
+ PR_smprintf_free(trailer); |
+ } |
+ PR_smprintf_free(header); |
+ } |
+ } else { |
+ (void)SECITEM_CopyItem(NULL, result, &signedReq); |
+ } |
+ |
+ if (!result->data) { |
+ oom: |
+ SECU_PrintError(progName, "out of memory"); |
+ PORT_SetError(SEC_ERROR_NO_MEMORY); |
+ rv = SECFailure; |
+ } |
+ |
+ PORT_FreeArena(arena, PR_FALSE); |
+ return rv; |
+} |
+ |
+static SECStatus ChangeTrustAttributes(CERTCertDBHandle *handle, |
+ PK11SlotInfo *slot, char *name, |
+ char *trusts, void *pwdata) { |
+ SECStatus rv; |
+ CERTCertificate *cert; |
+ CERTCertTrust *trust; |
+ |
+ cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); |
+ if (!cert) { |
+ SECU_PrintError(progName, "could not find certificate named \"%s\"", name); |
+ return SECFailure; |
+ } |
+ |
+ trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust)); |
+ if (!trust) { |
+ SECU_PrintError(progName, "unable to allocate cert trust"); |
+ return SECFailure; |
+ } |
+ |
+ /* This function only decodes these characters: pPwcTCu, */ |
+ rv = CERT_DecodeTrustString(trust, trusts); |
+ if (rv) { |
+ SECU_PrintError(progName, "unable to decode trust string"); |
+ return SECFailure; |
+ } |
+ |
+ /* CERT_ChangeCertTrust API does not have a way to pass in |
+ * a context, so NSS can't prompt for the password if it needs to. |
+ * check to see if the failure was token not logged in and |
+ * log in if need be. */ |
+ rv = CERT_ChangeCertTrust(handle, cert, trust); |
+ if (rv != SECSuccess) { |
+ if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) { |
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ return SECFailure; |
+ } |
+ rv = CERT_ChangeCertTrust(handle, cert, trust); |
+ } |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "unable to modify trust attributes"); |
+ return SECFailure; |
+ } |
+ } |
+ CERT_DestroyCertificate(cert); |
+ |
+ return SECSuccess; |
+} |
+ |
+static SECStatus DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii) { |
+ CERTCertificate *the_cert; |
+ CERTCertificateList *chain; |
+ int i, j; |
+ the_cert = SECU_FindCertByNicknameOrFilename(handle, name, ascii, NULL); |
+ if (!the_cert) { |
+ SECU_PrintError(progName, "Could not find: %s\n", name); |
+ return SECFailure; |
+ } |
+ chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE); |
+ CERT_DestroyCertificate(the_cert); |
+ if (!chain) { |
+ SECU_PrintError(progName, "Could not obtain chain for: %s\n", name); |
+ return SECFailure; |
+ } |
+ for (i = chain->len - 1; i >= 0; i--) { |
+ CERTCertificate *c; |
+ c = CERT_FindCertByDERCert(handle, &chain->certs[i]); |
+ for (j = i; j < chain->len - 1; j++) printf(" "); |
+ printf("\"%s\" [%s]\n\n", c->nickname, c->subjectName); |
+ CERT_DestroyCertificate(c); |
+ } |
+ CERT_DestroyCertificateList(chain); |
+ return SECSuccess; |
+} |
+ |
+static SECStatus outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, |
+ PRBool ascii, SECItem *extensionOID, |
+ PRFileDesc *outfile) { |
+ 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; |
+ |
+ /* List certs on a non-internal slot. */ |
+ if (!PK11_IsFriendly(slot) && PK11_NeedLogin(slot)) { |
+ SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, pwarg); |
+ if (newrv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ return SECFailure; |
+ } |
+ } |
+ if (name) { |
+ CERTCertificate *the_cert = |
+ SECU_FindCertByNicknameOrFilename(handle, name, ascii, NULL); |
+ if (!the_cert) { |
+ SECU_PrintError(progName, "Could not find cert: %s\n", name); |
+ return SECFailure; |
+ } |
+ /* Here, we have one cert with the desired nickname or email |
+ * address. Now, we will attempt to get a list of ALL certs |
+ * with the same subject name as the cert we have. That list |
+ * should contain, at a minimum, the one cert we have already found. |
+ * If the list of certs is empty (NULL), the libraries have failed. |
+ */ |
+ certs = CERT_CreateSubjectCertList(NULL, handle, &the_cert->derSubject, |
+ PR_Now(), PR_FALSE); |
+ CERT_DestroyCertificate(the_cert); |
+ if (!certs) { |
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
+ SECU_PrintError(progName, "problem printing certificates"); |
+ return SECFailure; |
+ } |
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs); |
+ node = CERT_LIST_NEXT(node)) { |
+ rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID, outfile); |
+ if (rv != SECSuccess) { |
+ break; |
+ } |
+ } |
+ } else if (email) { |
+ certs = PK11_FindCertsFromEmailAddress(email, NULL); |
+ if (!certs) { |
+ SECU_PrintError(progName, |
+ "Could not find certificates for email address: %s\n", |
+ email); |
+ return SECFailure; |
+ } |
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs); |
+ node = CERT_LIST_NEXT(node)) { |
+ rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID, outfile); |
+ if (rv != SECSuccess) { |
+ break; |
+ } |
+ } |
+ } else { |
+ certs = PK11_ListCertsInSlot(slot); |
+ if (certs) { |
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs); |
+ node = CERT_LIST_NEXT(node)) { |
+ SECU_PrintCertNickname(node, stdout); |
+ } |
+ rv = SECSuccess; |
+ } |
+ } |
+ if (certs) { |
+ CERT_DestroyCertList(certs); |
+ } |
+ if (rv) { |
+ SECU_PrintError(progName, "problem printing certificate nicknames"); |
+ return SECFailure; |
+ } |
+ |
+ return SECSuccess; /* not rv ?? */ |
+} |
+ |
+static SECStatus ListCerts(CERTCertDBHandle *handle, char *nickname, |
+ char *email, PK11SlotInfo *slot, PRBool raw, |
+ PRBool ascii, SECItem *extensionOID, |
+ PRFileDesc *outfile, secuPWData *pwdata) { |
+ SECStatus rv; |
+ |
+ if (!ascii && !raw && !nickname && !email) { |
+ PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n", "Certificate Nickname", |
+ "Trust Attributes", "", "SSL,S/MIME,JAR/XPI"); |
+ } |
+ if (slot == NULL) { |
+ CERTCertList *list; |
+ CERTCertListNode *node; |
+ |
+ list = PK11_ListCerts(PK11CertListAll, pwdata); |
+ for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); |
+ node = CERT_LIST_NEXT(node)) { |
+ SECU_PrintCertNickname(node, stdout); |
+ } |
+ CERT_DestroyCertList(list); |
+ return SECSuccess; |
+ } |
+ rv = listCerts(handle, nickname, email, slot, raw, ascii, extensionOID, |
+ outfile, pwdata); |
+ return rv; |
+} |
+ |
+static SECStatus DeleteCert(CERTCertDBHandle *handle, char *name) { |
+ SECStatus rv; |
+ CERTCertificate *cert; |
+ |
+ cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); |
+ if (!cert) { |
+ SECU_PrintError(progName, "could not find certificate named \"%s\"", name); |
+ return SECFailure; |
+ } |
+ |
+ rv = SEC_DeletePermCertificate(cert); |
+ CERT_DestroyCertificate(cert); |
+ if (rv) { |
+ SECU_PrintError(progName, "unable to delete certificate"); |
+ } |
+ return rv; |
+} |
+ |
+static SECStatus ValidateCert(CERTCertDBHandle *handle, char *name, char *date, |
+ char *certUsage, PRBool checkSig, PRBool logit, |
+ PRBool ascii, secuPWData *pwdata) { |
+ SECStatus rv; |
+ CERTCertificate *cert = NULL; |
+ PRTime timeBoundary; |
+ SECCertificateUsage usage; |
+ CERTVerifyLog reallog; |
+ CERTVerifyLog *log = NULL; |
+ |
+ if (!certUsage) { |
+ PORT_SetError(SEC_ERROR_INVALID_ARGS); |
+ return (SECFailure); |
+ } |
+ |
+ switch (*certUsage) { |
+ 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; |
+ case 'V': |
+ usage = certificateUsageSSLServer; |
+ break; |
+ case 'S': |
+ usage = certificateUsageEmailSigner; |
+ break; |
+ case 'R': |
+ usage = certificateUsageEmailRecipient; |
+ break; |
+ case 'J': |
+ usage = certificateUsageObjectSigner; |
+ break; |
+ default: |
+ PORT_SetError(SEC_ERROR_INVALID_ARGS); |
+ return (SECFailure); |
+ } |
+ do { |
+ cert = SECU_FindCertByNicknameOrFilename(handle, name, ascii, NULL); |
+ if (!cert) { |
+ SECU_PrintError(progName, "could not find certificate named \"%s\"", |
+ name); |
+ GEN_BREAK(SECFailure) |
} |
- rv = SEC_DerSignData(arena, &signedReq, encoding->data, encoding->len, |
- privk, signAlgTag); |
- if (rv) { |
- PORT_FreeArena (arena, PR_FALSE); |
- SECU_PrintError(progName, "signing of data failed"); |
- return SECFailure; |
+ if (date != NULL) { |
+ rv = DER_AsciiToTime(&timeBoundary, date); |
+ if (rv) { |
+ SECU_PrintError(progName, "invalid input date"); |
+ GEN_BREAK(SECFailure) |
+ } |
+ } else { |
+ timeBoundary = PR_Now(); |
} |
- /* Encode request in specified format */ |
- if (ascii) { |
- char *obuf; |
- char *header, *name, *email, *org, *state, *country; |
+ if (logit) { |
+ log = &reallog; |
- obuf = BTOA_ConvertItemToAscii(&signedReq); |
- if (!obuf) { |
- goto oom; |
- } |
- |
- name = CERT_GetCommonName(subject); |
- if (!name) { |
- name = PORT_Strdup("(not specified)"); |
- } |
- |
- if (!phone) |
- phone = strdup("(not specified)"); |
- |
- email = CERT_GetCertEmailAddress(subject); |
- if (!email) |
- email = PORT_Strdup("(not specified)"); |
- |
- org = CERT_GetOrgName(subject); |
- if (!org) |
- org = PORT_Strdup("(not specified)"); |
- |
- state = CERT_GetStateName(subject); |
- if (!state) |
- state = PORT_Strdup("(not specified)"); |
- |
- country = CERT_GetCountryName(subject); |
- if (!country) |
- country = PORT_Strdup("(not specified)"); |
- |
- header = PR_smprintf( |
- "\nCertificate request generated by Netscape certutil\n" |
- "Phone: %s\n\n" |
- "Common Name: %s\n" |
- "Email: %s\n" |
- "Organization: %s\n" |
- "State: %s\n" |
- "Country: %s\n\n" |
- "%s\n", |
- phone, name, email, org, state, country, NS_CERTREQ_HEADER); |
- |
- PORT_Free(name); |
- PORT_Free(email); |
- PORT_Free(org); |
- PORT_Free(state); |
- PORT_Free(country); |
- |
- if (header) { |
- char * trailer = PR_smprintf("\n%s\n", NS_CERTREQ_TRAILER); |
- if (trailer) { |
- PRUint32 headerLen = PL_strlen(header); |
- PRUint32 obufLen = PL_strlen(obuf); |
- PRUint32 trailerLen = PL_strlen(trailer); |
- SECITEM_AllocItem(NULL, result, |
- headerLen + obufLen + trailerLen); |
- if (result->data) { |
- PORT_Memcpy(result->data, header, headerLen); |
- PORT_Memcpy(result->data + headerLen, obuf, obufLen); |
- PORT_Memcpy(result->data + headerLen + obufLen, |
- trailer, trailerLen); |
- } |
- PR_smprintf_free(trailer); |
- } |
- PR_smprintf_free(header); |
- } |
- } else { |
- (void) SECITEM_CopyItem(NULL, result, &signedReq); |
+ log->count = 0; |
+ log->head = NULL; |
+ log->tail = NULL; |
+ log->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
+ if (log->arena == NULL) { |
+ SECU_PrintError(progName, "out of memory"); |
+ GEN_BREAK(SECFailure) |
+ } |
} |
- if (!result->data) { |
-oom: SECU_PrintError(progName, "out of memory"); |
- PORT_SetError(SEC_ERROR_NO_MEMORY); |
- rv = SECFailure; |
+ rv = CERT_VerifyCertificate(handle, cert, checkSig, usage, timeBoundary, |
+ pwdata, log, &usage); |
+ if (log) { |
+ if (log->head == NULL) { |
+ fprintf(stdout, "%s: certificate is valid\n", progName); |
+ GEN_BREAK(SECSuccess) |
+ } else { |
+ char *name; |
+ CERTVerifyLogNode *node; |
+ |
+ node = log->head; |
+ while (node) { |
+ if (node->cert->nickname != NULL) { |
+ name = node->cert->nickname; |
+ } else { |
+ name = node->cert->subjectName; |
+ } |
+ fprintf(stderr, "%s : %s\n", name, SECU_Strerror(node->error)); |
+ CERT_DestroyCertificate(node->cert); |
+ node = node->next; |
+ } |
+ } |
+ } else { |
+ if (rv != SECSuccess) { |
+ PRErrorCode perr = PORT_GetError(); |
+ fprintf(stdout, "%s: certificate is invalid: %s\n", progName, |
+ SECU_Strerror(perr)); |
+ GEN_BREAK(SECFailure) |
+ } |
+ fprintf(stdout, "%s: certificate is valid\n", progName); |
+ GEN_BREAK(SECSuccess) |
} |
+ } while (0); |
- PORT_FreeArena (arena, PR_FALSE); |
- return rv; |
+ if (cert) { |
+ CERT_DestroyCertificate(cert); |
+ } |
+ |
+ return (rv); |
} |
-static SECStatus |
-ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot, |
- char *name, char *trusts, void *pwdata) |
-{ |
- SECStatus rv; |
- CERTCertificate *cert; |
- CERTCertTrust *trust; |
- |
- cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); |
- if (!cert) { |
- SECU_PrintError(progName, "could not find certificate named \"%s\"", |
- name); |
- return SECFailure; |
- } |
- |
- trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust)); |
- if (!trust) { |
- SECU_PrintError(progName, "unable to allocate cert trust"); |
- return SECFailure; |
- } |
- |
- /* This function only decodes these characters: pPwcTCu, */ |
- rv = CERT_DecodeTrustString(trust, trusts); |
- if (rv) { |
- SECU_PrintError(progName, "unable to decode trust string"); |
- return SECFailure; |
- } |
- |
- /* CERT_ChangeCertTrust API does not have a way to pass in |
- * a context, so NSS can't prompt for the password if it needs to. |
- * check to see if the failure was token not logged in and |
- * log in if need be. */ |
- rv = CERT_ChangeCertTrust(handle, cert, trust); |
- if (rv != SECSuccess) { |
- if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) { |
- rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- return SECFailure; |
- } |
- rv = CERT_ChangeCertTrust(handle, cert, trust); |
- } |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "unable to modify trust attributes"); |
- return SECFailure; |
- } |
- } |
- CERT_DestroyCertificate(cert); |
- |
- return SECSuccess; |
-} |
- |
-static SECStatus |
-DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii) |
-{ |
- CERTCertificate *the_cert; |
- CERTCertificateList *chain; |
- int i, j; |
- the_cert = SECU_FindCertByNicknameOrFilename(handle, name, |
- ascii, NULL); |
- if (!the_cert) { |
- SECU_PrintError(progName, "Could not find: %s\n", name); |
- return SECFailure; |
- } |
- chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE); |
- CERT_DestroyCertificate(the_cert); |
- if (!chain) { |
- SECU_PrintError(progName, "Could not obtain chain for: %s\n", name); |
- return SECFailure; |
- } |
- for (i=chain->len-1; i>=0; i--) { |
- CERTCertificate *c; |
- c = CERT_FindCertByDERCert(handle, &chain->certs[i]); |
- for (j=i; j<chain->len-1; j++) printf(" "); |
- printf("\"%s\" [%s]\n\n", c->nickname, c->subjectName); |
- CERT_DestroyCertificate(c); |
- } |
- CERT_DestroyCertificateList(chain); |
- return SECSuccess; |
-} |
- |
-static SECStatus |
-outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, PRBool ascii, |
- SECItem *extensionOID, PRFileDesc *outfile) |
-{ |
- 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; |
- |
- /* List certs on a non-internal slot. */ |
- if (!PK11_IsFriendly(slot) && PK11_NeedLogin(slot)) { |
- SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, pwarg); |
- if (newrv != SECSuccess) { |
- SECU_PrintError(progName, "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- return SECFailure; |
- } |
- } |
- if (name) { |
- CERTCertificate *the_cert = |
- SECU_FindCertByNicknameOrFilename(handle, name, ascii, NULL); |
- if (!the_cert) { |
- SECU_PrintError(progName, "Could not find cert: %s\n", name); |
- return SECFailure; |
- } |
- /* Here, we have one cert with the desired nickname or email |
- * address. Now, we will attempt to get a list of ALL certs |
- * with the same subject name as the cert we have. That list |
- * should contain, at a minimum, the one cert we have already found. |
- * If the list of certs is empty (NULL), the libraries have failed. |
- */ |
- certs = CERT_CreateSubjectCertList(NULL, handle, &the_cert->derSubject, |
- PR_Now(), PR_FALSE); |
- CERT_DestroyCertificate(the_cert); |
- if (!certs) { |
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
- SECU_PrintError(progName, "problem printing certificates"); |
- return SECFailure; |
- } |
- for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs); |
- node = CERT_LIST_NEXT(node)) { |
- rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID, |
- outfile); |
- if (rv != SECSuccess) { |
- break; |
- } |
- } |
- } else if (email) { |
- certs = PK11_FindCertsFromEmailAddress(email, NULL); |
- if (!certs) { |
- SECU_PrintError(progName, |
- "Could not find certificates for email address: %s\n", |
- email); |
- return SECFailure; |
- } |
- for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs); |
- node = CERT_LIST_NEXT(node)) { |
- rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID, |
- outfile); |
- if (rv != SECSuccess) { |
- break; |
- } |
- } |
- } else { |
- certs = PK11_ListCertsInSlot(slot); |
- if (certs) { |
- for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs); |
- node = CERT_LIST_NEXT(node)) { |
- SECU_PrintCertNickname(node,stdout); |
- } |
- rv = SECSuccess; |
- } |
- } |
- if (certs) { |
- CERT_DestroyCertList(certs); |
- } |
- if (rv) { |
- SECU_PrintError(progName, "problem printing certificate nicknames"); |
- return SECFailure; |
- } |
- |
- return SECSuccess; /* not rv ?? */ |
-} |
- |
-static SECStatus |
-ListCerts(CERTCertDBHandle *handle, char *nickname, char *email, |
- PK11SlotInfo *slot, PRBool raw, PRBool ascii, |
- SECItem *extensionOID, |
- PRFileDesc *outfile, secuPWData *pwdata) |
-{ |
- SECStatus rv; |
- |
- if (!ascii && !raw && !nickname && !email) { |
- PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n", |
- "Certificate Nickname", "Trust Attributes", "", |
- "SSL,S/MIME,JAR/XPI"); |
- } |
- if (slot == NULL) { |
- CERTCertList *list; |
- CERTCertListNode *node; |
- |
- list = PK11_ListCerts(PK11CertListAll, pwdata); |
- for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); |
- node = CERT_LIST_NEXT(node)) { |
- SECU_PrintCertNickname(node, stdout); |
- } |
- CERT_DestroyCertList(list); |
- return SECSuccess; |
- } |
- rv = listCerts(handle, nickname, email, slot, raw, ascii, |
- extensionOID, outfile, pwdata); |
- return rv; |
-} |
- |
-static SECStatus |
-DeleteCert(CERTCertDBHandle *handle, char *name) |
-{ |
- SECStatus rv; |
- CERTCertificate *cert; |
- |
- cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); |
- if (!cert) { |
- SECU_PrintError(progName, "could not find certificate named \"%s\"", |
- name); |
- return SECFailure; |
- } |
- |
- rv = SEC_DeletePermCertificate(cert); |
- CERT_DestroyCertificate(cert); |
- if (rv) { |
- SECU_PrintError(progName, "unable to delete certificate"); |
- } |
- return rv; |
-} |
- |
-static SECStatus |
-ValidateCert(CERTCertDBHandle *handle, char *name, char *date, |
- char *certUsage, PRBool checkSig, PRBool logit, |
- PRBool ascii, secuPWData *pwdata) |
-{ |
- SECStatus rv; |
- CERTCertificate *cert = NULL; |
- PRTime timeBoundary; |
- SECCertificateUsage usage; |
- CERTVerifyLog reallog; |
- CERTVerifyLog *log = NULL; |
- |
- if (!certUsage) { |
- PORT_SetError (SEC_ERROR_INVALID_ARGS); |
- return (SECFailure); |
- } |
- |
- switch (*certUsage) { |
- 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; |
- case 'V': |
- usage = certificateUsageSSLServer; |
- break; |
- case 'S': |
- usage = certificateUsageEmailSigner; |
- break; |
- case 'R': |
- usage = certificateUsageEmailRecipient; |
- break; |
- case 'J': |
- usage = certificateUsageObjectSigner; |
- break; |
- default: |
- PORT_SetError (SEC_ERROR_INVALID_ARGS); |
- return (SECFailure); |
- } |
- do { |
- cert = SECU_FindCertByNicknameOrFilename(handle, name, ascii, |
- NULL); |
- if (!cert) { |
- SECU_PrintError(progName, "could not find certificate named \"%s\"", |
- name); |
- GEN_BREAK (SECFailure) |
- } |
- |
- if (date != NULL) { |
- rv = DER_AsciiToTime(&timeBoundary, date); |
- if (rv) { |
- SECU_PrintError(progName, "invalid input date"); |
- GEN_BREAK (SECFailure) |
- } |
- } else { |
- timeBoundary = PR_Now(); |
- } |
- |
- if ( logit ) { |
- log = &reallog; |
- |
- log->count = 0; |
- log->head = NULL; |
- log->tail = NULL; |
- log->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if ( log->arena == NULL ) { |
- SECU_PrintError(progName, "out of memory"); |
- GEN_BREAK (SECFailure) |
- } |
- } |
- |
- rv = CERT_VerifyCertificate(handle, cert, checkSig, usage, |
- timeBoundary, pwdata, log, &usage); |
- if ( log ) { |
- if ( log->head == NULL ) { |
- fprintf(stdout, "%s: certificate is valid\n", progName); |
- GEN_BREAK (SECSuccess) |
- } else { |
- char *name; |
- CERTVerifyLogNode *node; |
- |
- node = log->head; |
- while ( node ) { |
- if ( node->cert->nickname != NULL ) { |
- name = node->cert->nickname; |
- } else { |
- name = node->cert->subjectName; |
- } |
- fprintf(stderr, "%s : %s\n", name, |
- SECU_Strerror(node->error)); |
- CERT_DestroyCertificate(node->cert); |
- node = node->next; |
- } |
- } |
- } else { |
- if (rv != SECSuccess) { |
- PRErrorCode perr = PORT_GetError(); |
- fprintf(stdout, "%s: certificate is invalid: %s\n", |
- progName, SECU_Strerror(perr)); |
- GEN_BREAK (SECFailure) |
- } |
- fprintf(stdout, "%s: certificate is valid\n", progName); |
- GEN_BREAK (SECSuccess) |
- } |
- } while (0); |
- |
- if (cert) { |
- CERT_DestroyCertificate(cert); |
- } |
- |
- return (rv); |
-} |
- |
-static PRBool |
-ItemIsPrintableASCII(const SECItem * item) |
-{ |
- unsigned char *src = item->data; |
- unsigned int len = item->len; |
- while (len-- > 0) { |
- unsigned char uc = *src++; |
- if (uc < 0x20 || uc > 0x7e) |
- return PR_FALSE; |
- } |
- return PR_TRUE; |
+static PRBool ItemIsPrintableASCII(const SECItem *item) { |
+ unsigned char *src = item->data; |
+ unsigned int len = item->len; |
+ while (len-- > 0) { |
+ unsigned char uc = *src++; |
+ if (uc < 0x20 || uc > 0x7e) return PR_FALSE; |
+ } |
+ return PR_TRUE; |
} |
/* Caller ensures that dst is at least item->len*2+1 bytes long */ |
-static void |
-SECItemToHex(const SECItem * item, char * dst) |
-{ |
- if (dst && item && item->data) { |
- unsigned char * src = item->data; |
- unsigned int len = item->len; |
- for (; len > 0; --len, dst += 2) { |
- sprintf(dst, "%02x", *src++); |
- } |
- *dst = '\0'; |
+static void SECItemToHex(const SECItem *item, char *dst) { |
+ if (dst && item && item->data) { |
+ unsigned char *src = item->data; |
+ unsigned int len = item->len; |
+ for (; len > 0; --len, dst += 2) { |
+ sprintf(dst, "%02x", *src++); |
} |
+ *dst = '\0'; |
+ } |
} |
-static const char * const keyTypeName[] = { |
- "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec" }; |
+static const char *const keyTypeName[] = {"null", "rsa", "dsa", "fortezza", |
+ "dh", "kea", "ec"}; |
#define MAX_CKA_ID_BIN_LEN 20 |
#define MAX_CKA_ID_STR_LEN 40 |
/* print key number, key ID (in hex or ASCII), key label (nickname) */ |
-static SECStatus |
-PrintKey(PRFileDesc *out, const char *nickName, int count, |
- SECKEYPrivateKey *key, void *pwarg) |
-{ |
- SECItem * ckaID; |
- char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; |
+static SECStatus PrintKey(PRFileDesc *out, const char *nickName, int count, |
+ SECKEYPrivateKey *key, void *pwarg) { |
+ SECItem *ckaID; |
+ char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; |
- pwarg = NULL; |
- ckaID = PK11_GetLowLevelKeyIDForPrivateKey(key); |
- if (!ckaID) { |
- strcpy(ckaIDbuf, "(no CKA_ID)"); |
- } else if (ItemIsPrintableASCII(ckaID)) { |
- int len = PR_MIN(MAX_CKA_ID_STR_LEN, ckaID->len); |
- ckaIDbuf[0] = '"'; |
- memcpy(ckaIDbuf + 1, ckaID->data, len); |
- ckaIDbuf[1 + len] = '"'; |
- ckaIDbuf[2 + len] = '\0'; |
- } else { |
- /* print ckaid in hex */ |
- SECItem idItem = *ckaID; |
- if (idItem.len > MAX_CKA_ID_BIN_LEN) |
- idItem.len = MAX_CKA_ID_BIN_LEN; |
- SECItemToHex(&idItem, ckaIDbuf); |
- } |
+ pwarg = NULL; |
+ ckaID = PK11_GetLowLevelKeyIDForPrivateKey(key); |
+ if (!ckaID) { |
+ strcpy(ckaIDbuf, "(no CKA_ID)"); |
+ } else if (ItemIsPrintableASCII(ckaID)) { |
+ int len = PR_MIN(MAX_CKA_ID_STR_LEN, ckaID->len); |
+ ckaIDbuf[0] = '"'; |
+ memcpy(ckaIDbuf + 1, ckaID->data, len); |
+ ckaIDbuf[1 + len] = '"'; |
+ ckaIDbuf[2 + len] = '\0'; |
+ } else { |
+ /* print ckaid in hex */ |
+ SECItem idItem = *ckaID; |
+ if (idItem.len > MAX_CKA_ID_BIN_LEN) idItem.len = MAX_CKA_ID_BIN_LEN; |
+ SECItemToHex(&idItem, ckaIDbuf); |
+ } |
- PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count, |
- keyTypeName[key->keyType], ckaIDbuf, nickName); |
- SECITEM_ZfreeItem(ckaID, PR_TRUE); |
+ PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count, |
+ keyTypeName[key->keyType], ckaIDbuf, nickName); |
+ SECITEM_ZfreeItem(ckaID, PR_TRUE); |
- return SECSuccess; |
+ return SECSuccess; |
} |
/* returns SECSuccess if ANY keys are found, SECFailure otherwise. */ |
-static SECStatus |
-ListKeysInSlot(PK11SlotInfo *slot, const char *nickName, KeyType keyType, |
- void *pwarg) |
-{ |
- SECKEYPrivateKeyList *list; |
- SECKEYPrivateKeyListNode *node; |
- int count = 0; |
+static SECStatus ListKeysInSlot(PK11SlotInfo *slot, const char *nickName, |
+ KeyType keyType, void *pwarg) { |
+ SECKEYPrivateKeyList *list; |
+ SECKEYPrivateKeyListNode *node; |
+ int count = 0; |
- if (PK11_NeedLogin(slot)) { |
- SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwarg); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- return SECFailure; |
+ if (PK11_NeedLogin(slot)) { |
+ SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwarg); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ return SECFailure; |
+ } |
+ } |
+ |
+ if (nickName && nickName[0]) |
+ list = PK11_ListPrivKeysInSlot(slot, (char *)nickName, pwarg); |
+ else |
+ list = PK11_ListPrivateKeysInSlot(slot); |
+ if (list == NULL) { |
+ SECU_PrintError(progName, "problem listing keys"); |
+ return SECFailure; |
+ } |
+ for (node = PRIVKEY_LIST_HEAD(list); !PRIVKEY_LIST_END(node, list); |
+ node = PRIVKEY_LIST_NEXT(node)) { |
+ char *keyName; |
+ static const char orphan[] = {"(orphan)"}; |
+ |
+ if (keyType != nullKey && keyType != node->key->keyType) continue; |
+ keyName = PK11_GetPrivateKeyNickname(node->key); |
+ if (!keyName || !keyName[0]) { |
+ /* Try extra hard to find nicknames for keys that lack them. */ |
+ CERTCertificate *cert; |
+ PORT_Free((void *)keyName); |
+ keyName = NULL; |
+ cert = PK11_GetCertFromPrivateKey(node->key); |
+ if (cert) { |
+ if (cert->nickname && cert->nickname[0]) { |
+ keyName = PORT_Strdup(cert->nickname); |
+ } else if (cert->emailAddr && cert->emailAddr[0]) { |
+ keyName = PORT_Strdup(cert->emailAddr); |
} |
+ CERT_DestroyCertificate(cert); |
+ } |
} |
+ if (nickName) { |
+ if (!keyName || PL_strcmp(keyName, nickName)) { |
+ /* PKCS#11 module returned unwanted keys */ |
+ PORT_Free((void *)keyName); |
+ continue; |
+ } |
+ } |
+ if (!keyName) keyName = (char *)orphan; |
- if (nickName && nickName[0]) |
- list = PK11_ListPrivKeysInSlot(slot, (char *)nickName, pwarg); |
- else |
- list = PK11_ListPrivateKeysInSlot(slot); |
- if (list == NULL) { |
- SECU_PrintError(progName, "problem listing keys"); |
- return SECFailure; |
- } |
- for (node=PRIVKEY_LIST_HEAD(list); |
- !PRIVKEY_LIST_END(node,list); |
- node=PRIVKEY_LIST_NEXT(node)) { |
- char * keyName; |
- static const char orphan[] = { "(orphan)" }; |
+ PrintKey(PR_STDOUT, keyName, count, node->key, pwarg); |
- if (keyType != nullKey && keyType != node->key->keyType) |
- continue; |
- keyName = PK11_GetPrivateKeyNickname(node->key); |
- if (!keyName || !keyName[0]) { |
- /* Try extra hard to find nicknames for keys that lack them. */ |
- CERTCertificate * cert; |
- PORT_Free((void *)keyName); |
- keyName = NULL; |
- cert = PK11_GetCertFromPrivateKey(node->key); |
- if (cert) { |
- if (cert->nickname && cert->nickname[0]) { |
- keyName = PORT_Strdup(cert->nickname); |
- } else if (cert->emailAddr && cert->emailAddr[0]) { |
- keyName = PORT_Strdup(cert->emailAddr); |
- } |
- CERT_DestroyCertificate(cert); |
- } |
- } |
- if (nickName) { |
- if (!keyName || PL_strcmp(keyName,nickName)) { |
- /* PKCS#11 module returned unwanted keys */ |
- PORT_Free((void *)keyName); |
- continue; |
- } |
- } |
- if (!keyName) |
- keyName = (char *)orphan; |
+ if (keyName != (char *)orphan) PORT_Free((void *)keyName); |
+ count++; |
+ } |
+ SECKEY_DestroyPrivateKeyList(list); |
- PrintKey(PR_STDOUT, keyName, count, node->key, pwarg); |
- |
- if (keyName != (char *)orphan) |
- PORT_Free((void *)keyName); |
- count++; |
- } |
- SECKEY_DestroyPrivateKeyList(list); |
- |
- if (count == 0) { |
- PR_fprintf(PR_STDOUT, "%s: no keys found\n", progName); |
- return SECFailure; |
- } |
- return SECSuccess; |
+ if (count == 0) { |
+ PR_fprintf(PR_STDOUT, "%s: no keys found\n", progName); |
+ return SECFailure; |
+ } |
+ return SECSuccess; |
} |
/* returns SECSuccess if ANY keys are found, SECFailure otherwise. */ |
-static SECStatus |
-ListKeys(PK11SlotInfo *slot, const char *nickName, int index, |
- KeyType keyType, PRBool dopriv, secuPWData *pwdata) |
-{ |
- SECStatus rv = SECFailure; |
- static const char fmt[] = \ |
- "%s: Checking token \"%.33s\" in slot \"%.65s\"\n"; |
+static SECStatus ListKeys(PK11SlotInfo *slot, const char *nickName, int index, |
+ KeyType keyType, PRBool dopriv, secuPWData *pwdata) { |
+ SECStatus rv = SECFailure; |
+ static const char fmt[] = "%s: Checking token \"%.33s\" in slot \"%.65s\"\n"; |
- if (slot == NULL) { |
- PK11SlotList *list; |
- PK11SlotListElement *le; |
+ if (slot == NULL) { |
+ PK11SlotList *list; |
+ PK11SlotListElement *le; |
- list= PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,pwdata); |
- if (list) { |
- for (le = list->head; le; le = le->next) { |
- PR_fprintf(PR_STDOUT, fmt, progName, |
- PK11_GetTokenName(le->slot), |
- PK11_GetSlotName(le->slot)); |
- rv &= ListKeysInSlot(le->slot,nickName,keyType,pwdata); |
- } |
- PK11_FreeSlotList(list); |
- } |
- } else { |
- PR_fprintf(PR_STDOUT, fmt, progName, PK11_GetTokenName(slot), |
- PK11_GetSlotName(slot)); |
- rv = ListKeysInSlot(slot,nickName,keyType,pwdata); |
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, pwdata); |
+ if (list) { |
+ for (le = list->head; le; le = le->next) { |
+ PR_fprintf(PR_STDOUT, fmt, progName, PK11_GetTokenName(le->slot), |
+ PK11_GetSlotName(le->slot)); |
+ rv &= ListKeysInSlot(le->slot, nickName, keyType, pwdata); |
+ } |
+ PK11_FreeSlotList(list); |
} |
- return rv; |
+ } else { |
+ PR_fprintf(PR_STDOUT, fmt, progName, PK11_GetTokenName(slot), |
+ PK11_GetSlotName(slot)); |
+ rv = ListKeysInSlot(slot, nickName, keyType, pwdata); |
+ } |
+ return rv; |
} |
-static SECStatus |
-DeleteKey(char *nickname, secuPWData *pwdata) |
-{ |
- SECStatus rv; |
- CERTCertificate *cert; |
- PK11SlotInfo *slot; |
+static SECStatus DeleteKey(char *nickname, secuPWData *pwdata) { |
+ SECStatus rv; |
+ CERTCertificate *cert; |
+ PK11SlotInfo *slot; |
- slot = PK11_GetInternalKeySlot(); |
- if (PK11_NeedLogin(slot)) { |
- SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- return SECFailure; |
- } |
+ slot = PK11_GetInternalKeySlot(); |
+ if (PK11_NeedLogin(slot)) { |
+ SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwdata); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ return SECFailure; |
} |
- cert = PK11_FindCertFromNickname(nickname, pwdata); |
- if (!cert) { |
- PK11_FreeSlot(slot); |
- return SECFailure; |
- } |
- rv = PK11_DeleteTokenCertAndKey(cert, pwdata); |
- if (rv != SECSuccess) { |
- SECU_PrintError("problem deleting private key \"%s\"\n", nickname); |
- } |
- CERT_DestroyCertificate(cert); |
+ } |
+ cert = PK11_FindCertFromNickname(nickname, pwdata); |
+ if (!cert) { |
PK11_FreeSlot(slot); |
- return rv; |
+ return SECFailure; |
+ } |
+ rv = PK11_DeleteTokenCertAndKey(cert, pwdata); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError("problem deleting private key \"%s\"\n", nickname); |
+ } |
+ CERT_DestroyCertificate(cert); |
+ PK11_FreeSlot(slot); |
+ return rv; |
} |
- |
/* |
* L i s t M o d u l e s |
* |
* Print a list of the PKCS11 modules that are |
* available. This is useful for smartcard people to |
* make sure they have the drivers loaded. |
* |
*/ |
-static SECStatus |
-ListModules(void) |
-{ |
- PK11SlotList *list; |
- PK11SlotListElement *le; |
+static SECStatus ListModules(void) { |
+ PK11SlotList *list; |
+ PK11SlotListElement *le; |
- /* get them all! */ |
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,NULL); |
- if (list == NULL) return SECFailure; |
+ /* get them all! */ |
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL); |
+ if (list == NULL) return SECFailure; |
- /* look at each slot*/ |
- for (le = list->head ; le; le = le->next) { |
- printf ("\n"); |
- printf (" slot: %s\n", PK11_GetSlotName(le->slot)); |
- printf (" token: %s\n", PK11_GetTokenName(le->slot)); |
- } |
- PK11_FreeSlotList(list); |
+ /* look at each slot*/ |
+ for (le = list->head; le; le = le->next) { |
+ printf("\n"); |
+ printf(" slot: %s\n", PK11_GetSlotName(le->slot)); |
+ printf(" token: %s\n", PK11_GetTokenName(le->slot)); |
+ } |
+ PK11_FreeSlotList(list); |
- return SECSuccess; |
+ return SECSuccess; |
} |
-static void |
-PrintSyntax(char *progName) |
-{ |
-#define FPS fprintf(stderr, |
+static void PrintSyntax(char *progName) { |
+#define FPS fprintf(stderr, |
FPS "Type %s -H for more detailed descriptions\n", progName); |
FPS "Usage: %s -N [-d certdir] [-P dbprefix] [-f pwfile] [--empty-password]\n", progName); |
FPS "Usage: %s -T [-d certdir] [-P dbprefix] [-h token-name]\n" |
"\t\t [-f pwfile] [-0 SSO-password]\n", progName); |
FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", |
progName); |
FPS "\t%s -B -i batch-file\n", progName); |
FPS "\t%s -C [-c issuer-name | -x] -i cert-request-file -o cert-file\n" |
@@ -1034,60 +978,53 @@ PrintSyntax(char *progName) |
"\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); |
FPS "\t%s -U [-X] [-d certdir] [-P dbprefix]\n", progName); |
exit(1); |
} |
enum usage_level { |
- usage_all = 0, usage_selected = 1 |
+ usage_all = 0, |
+ usage_selected = 1 |
}; |
static void luCommonDetailsAE(); |
-static void luA(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "A")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luA(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "A")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Add a certificate to the database (create if needed)\n", |
"-A"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
- if (ul == usage_all) { |
+ if (ul == usage_selected && !is_my_command) return; |
+ if (ul == usage_all) { |
FPS "%-20s\n", " All options under -E apply"); |
- } |
- else { |
- luCommonDetailsAE(); |
- } |
+ } else { |
+ luCommonDetailsAE(); |
+ } |
} |
-static void luB(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "B")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luB(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "B")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Run a series of certutil commands from a batch file\n", "-B"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Specify the batch file\n", " -i batch-file"); |
} |
-static void luE(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "E")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luE(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "E")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Add an Email certificate to the database (create if needed)\n", |
"-E"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
- luCommonDetailsAE(); |
+ if (ul == usage_selected && !is_my_command) return; |
+ luCommonDetailsAE(); |
} |
-static void luCommonDetailsAE() |
-{ |
+static void luCommonDetailsAE() { |
FPS "%-20s Specify the nickname of the certificate to add\n", |
" -n cert-name"); |
FPS "%-20s Set the certificate trust attributes:\n", |
" -t trustargs"); |
FPS "%-25s trustargs is of the form x,y,z where x is for SSL, y is for S/MIME,\n", ""); |
FPS "%-25s and z is for code signing. Use ,, for no explicit trust.\n", ""); |
FPS "%-25s p \t prohibited (explicitly distrusted)\n", ""); |
FPS "%-25s P \t trusted peer\n", ""); |
@@ -1105,24 +1042,22 @@ static void luCommonDetailsAE() |
" -P dbprefix"); |
FPS "%-20s The input certificate is encoded in ASCII (RFC1113)\n", |
" -a"); |
FPS "%-20s Specify the certificate file (default is stdin)\n", |
" -i input"); |
FPS "\n"); |
} |
-static void luC(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "C")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luC(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "C")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Create a new binary certificate from a BINARY cert request\n", |
"-C"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s The nickname of the issuer cert\n", |
" -c issuer-name"); |
FPS "%-20s The BINARY certificate request file\n", |
" -i cert-request "); |
FPS "%-20s Output binary cert to this file (default is stdout)\n", |
" -o output-cert"); |
FPS "%-20s Self sign\n", |
" -x"); |
@@ -1170,24 +1105,22 @@ static void luC(enum usage_level ul, con |
" -7 emailAddrs"); |
FPS "%-20s Create an dns subject alt name extension\n", |
" -8 dnsNames"); |
FPS "%-20s The input certificate request is encoded in ASCII (RFC1113)\n", |
" -a"); |
FPS "\n"); |
} |
-static void luG(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "G")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luG(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "G")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Generate a new key pair\n", |
"-G"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Name of token in which to generate key (default is internal)\n", |
" -h token-name"); |
#ifndef NSS_DISABLE_ECC |
FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", |
" -k key-type"); |
FPS "%-20s Key size in bits, (min %d, max %d, default %d) (not for ec)\n", |
" -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); |
#else |
@@ -1245,78 +1178,67 @@ static void luG(enum usage_level ul, con |
"%-20s PKCS #11 key Operation Flags.\n", |
" --keyOpFlagsOff opflags", ""); |
FPS "%-20s Comma separated list of one or more of the following:\n", ""); |
FPS "%-20s encrypt, decrypt, sign, sign_recover, verify,\n", ""); |
FPS "%-20s verify_recover, wrap, unwrap, derive\n", ""); |
FPS "\n"); |
} |
-static void luD(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "D")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luD(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "D")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Delete a certificate from the database\n", |
"-D"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s The nickname of the cert to delete\n", |
" -n cert-name"); |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "\n"); |
- |
} |
-static void luF(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "F")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luF(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "F")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Delete a key from the database\n", |
"-F"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s The nickname of the key to delete\n", |
" -n cert-name"); |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "\n"); |
- |
} |
-static void luU(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "U")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luU(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "U")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s List all modules\n", /*, or print out a single named module\n",*/ |
"-U"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Module database directory (default is '~/.netscape')\n", |
" -d moddir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "%-20s force the database to open R/W\n", |
" -X"); |
FPS "\n"); |
- |
} |
-static void luK(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "K")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luK(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "K")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s List all private keys\n", |
"-K"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Name of token to search (\"all\" for all tokens)\n", |
" -h token-name "); |
FPS "%-20s Key type (\"all\" (default), \"dsa\"," |
#ifndef NSS_DISABLE_ECC |
" \"ec\"," |
#endif |
" \"rsa\")\n", |
@@ -1329,24 +1251,22 @@ static void luK(enum usage_level ul, con |
" -d keydir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "%-20s force the database to open R/W\n", |
" -X"); |
FPS "\n"); |
} |
-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) |
+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", |
"-L"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Name of token to search (\"all\" for all tokens)\n", |
" -h token-name "); |
FPS "%-20s Pretty print named cert (list all if unspecified)\n", |
" -n cert-name"); |
FPS "%-20s \n" |
"%-20s Pretty print cert with email address (list all if unspecified)\n", |
" --email email-address", ""); |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
@@ -1360,102 +1280,92 @@ static void luL(enum usage_level ul, con |
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"); |
} |
-static void luM(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "M")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luM(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "M")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Modify trust attributes of certificate\n", |
"-M"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s The nickname of the cert to modify\n", |
" -n cert-name"); |
FPS "%-20s Set the certificate trust attributes (see -A above)\n", |
" -t trustargs"); |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "\n"); |
} |
-static void luN(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "N")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luN(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "N")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Create a new certificate database\n", |
"-N"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "%-20s Specify the password file\n", |
" -f password-file"); |
FPS "%-20s use empty password when creating a new database\n", |
" --empty-password"); |
FPS "\n"); |
} |
-static void luT(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "T")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luT(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "T")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Reset the Key database or token\n", |
"-T"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "%-20s Token to reset (default is internal)\n", |
" -h token-name"); |
FPS "%-20s Set token's Site Security Officer password\n", |
" -0 SSO-password"); |
FPS "\n"); |
} |
-static void luO(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "O")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luO(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "O")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Print the chain of a certificate\n", |
"-O"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s The nickname of the cert to modify\n", |
" -n cert-name"); |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n", |
" -a"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "%-20s force the database to open R/W\n", |
" -X"); |
FPS "\n"); |
} |
-static void luR(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "R")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luR(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "R")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Generate a certificate request (stdout)\n", |
"-R"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Specify the subject name (using RFC1485)\n", |
" -s subject"); |
FPS "%-20s Output the cert request to this file\n", |
" -o output-req"); |
#ifndef NSS_DISABLE_ECC |
FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", |
#else |
FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", |
@@ -1492,76 +1402,70 @@ static void luR(enum usage_level ul, con |
" -a"); |
FPS "%-20s \n", |
" See -S for available extension options"); |
FPS "%-20s \n", |
" See -G for available key flag options"); |
FPS "\n"); |
} |
-static void luV(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "V")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luV(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "V")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Validate a certificate\n", |
"-V"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s The nickname of the cert to Validate\n", |
" -n cert-name"); |
FPS "%-20s validity time (\"YYMMDDHHMMSS[+HHMM|-HHMM|Z]\")\n", |
" -b time"); |
FPS "%-20s Check certificate signature \n", |
- " -e "); |
+ " -e "); |
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", ""); |
- FPS "%-25s J \t Object signer\n", ""); |
+ FPS "%-25s R \t Email Recipient\n", ""); |
+ FPS "%-25s O \t OCSP status responder\n", ""); |
+ FPS "%-25s J \t Object signer\n", ""); |
FPS "%-20s Cert database directory (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n", |
" -a"); |
FPS "%-20s Cert & Key database prefix\n", |
" -P dbprefix"); |
FPS "%-20s force the database to open R/W\n", |
" -X"); |
FPS "\n"); |
} |
-static void luW(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "W")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luW(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "W")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Change the key database password\n", |
"-W"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s cert and key database directory\n", |
" -d certdir"); |
FPS "%-20s Specify a file with the current password\n", |
" -f pwfile"); |
FPS "%-20s Specify a file with the new password in two lines\n", |
" -@ newpwfile"); |
FPS "\n"); |
} |
-static void luUpgradeMerge(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "upgrade-merge")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luUpgradeMerge(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "upgrade-merge")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Upgrade an old database and merge it into a new one\n", |
"--upgrade-merge"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Cert database directory to merge into (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix of the target database\n", |
" -P dbprefix"); |
FPS "%-20s Specify the password file for the target database\n", |
" -f pwfile"); |
FPS "%-20s \n%-20s Cert database directory to upgrade from\n", |
" --source-dir certdir", ""); |
@@ -1571,47 +1475,43 @@ static void luUpgradeMerge(enum usage_le |
" --upgrade-id uniqueID", ""); |
FPS "%-20s \n%-20s Name of the token while it is in upgrade state\n", |
" --upgrade-token-name name", ""); |
FPS "%-20s Specify the password file for the upgrade database\n", |
" -@ pwfile"); |
FPS "\n"); |
} |
-static void luMerge(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "merge")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luMerge(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "merge")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Merge source database into the target database\n", |
"--merge"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Cert database directory of target (default is ~/.netscape)\n", |
" -d certdir"); |
FPS "%-20s Cert & Key database prefix of the target database\n", |
" -P dbprefix"); |
FPS "%-20s Specify the password file for the target database\n", |
" -f pwfile"); |
FPS "%-20s \n%-20s Cert database directory of the source database\n", |
" --source-dir certdir", ""); |
FPS "%-20s \n%-20s Cert & Key database prefix of the source database\n", |
" --source-prefix dbprefix", ""); |
FPS "%-20s Specify the password file for the source database\n", |
" -@ pwfile"); |
FPS "\n"); |
} |
-static void luS(enum usage_level ul, const char *command) |
-{ |
- int is_my_command = (command && 0 == strcmp(command, "S")); |
- if (ul == usage_all || !command || is_my_command) |
+static void luS(enum usage_level ul, const char *command) { |
+ int is_my_command = (command && 0 == strcmp(command, "S")); |
+ if (ul == usage_all || !command || is_my_command) |
FPS "%-15s Make a certificate and add to database\n", |
"-S"); |
- if (ul == usage_selected && !is_my_command) |
- return; |
+ if (ul == usage_selected && !is_my_command) return; |
FPS "%-20s Specify the nickname of the cert\n", |
" -n key-name"); |
FPS "%-20s Specify the subject name (using RFC1485)\n", |
" -s subject"); |
FPS "%-20s The nickname of the issuer cert\n", |
" -c issuer-name"); |
FPS "%-20s Set the certificate trust attributes (see -A above)\n", |
" -t trustargs"); |
@@ -1698,1872 +1598,1750 @@ static void luS(enum usage_level ul, con |
"%-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"); |
} |
-static void LongUsage(char *progName, enum usage_level ul, const char *command) |
-{ |
- luA(ul, command); |
- luB(ul, command); |
- luE(ul, command); |
- luC(ul, command); |
- luG(ul, command); |
- luD(ul, command); |
- luF(ul, command); |
- luU(ul, command); |
- luK(ul, command); |
- luL(ul, command); |
- luM(ul, command); |
- luN(ul, command); |
- luT(ul, command); |
- luO(ul, command); |
- luR(ul, command); |
- luV(ul, command); |
- luW(ul, command); |
- luUpgradeMerge(ul, command); |
- luMerge(ul, command); |
- luS(ul, command); |
+static void LongUsage(char *progName, enum usage_level ul, |
+ const char *command) { |
+ luA(ul, command); |
+ luB(ul, command); |
+ luE(ul, command); |
+ luC(ul, command); |
+ luG(ul, command); |
+ luD(ul, command); |
+ luF(ul, command); |
+ luU(ul, command); |
+ luK(ul, command); |
+ luL(ul, command); |
+ luM(ul, command); |
+ luN(ul, command); |
+ luT(ul, command); |
+ luO(ul, command); |
+ luR(ul, command); |
+ luV(ul, command); |
+ luW(ul, command); |
+ luUpgradeMerge(ul, command); |
+ luMerge(ul, command); |
+ luS(ul, command); |
#undef FPS |
} |
-static void |
-Usage(char *progName) |
-{ |
- PR_fprintf(PR_STDERR, |
- "%s - Utility to manipulate NSS certificate databases\n\n" |
- "Usage: %s <command> -d <database-directory> <options>\n\n" |
- "Valid commands:\n", progName, progName); |
- LongUsage(progName, usage_selected, NULL); |
- PR_fprintf(PR_STDERR, "\n" |
- "%s -H <command> : Print available options for the given command\n" |
- "%s -H : Print complete help output of all commands and options\n" |
- "%s --syntax : Print a short summary of all commands and options\n", |
- progName, progName, progName); |
- exit(1); |
+static void Usage(char *progName) { |
+ PR_fprintf(PR_STDERR, |
+ "%s - Utility to manipulate NSS certificate databases\n\n" |
+ "Usage: %s <command> -d <database-directory> <options>\n\n" |
+ "Valid commands:\n", |
+ progName, progName); |
+ LongUsage(progName, usage_selected, NULL); |
+ PR_fprintf( |
+ PR_STDERR, |
+ "\n" |
+ "%s -H <command> : Print available options for the given command\n" |
+ "%s -H : Print complete help output of all commands and options\n" |
+ "%s --syntax : Print a short summary of all commands and options\n", |
+ progName, progName, progName); |
+ exit(1); |
} |
-static CERTCertificate * |
-MakeV1Cert( CERTCertDBHandle * handle, |
- CERTCertificateRequest *req, |
- char * issuerNickName, |
- PRBool selfsign, |
- unsigned int serialNumber, |
- int warpmonths, |
- int validityMonths) |
-{ |
- CERTCertificate *issuerCert = NULL; |
- CERTValidity *validity; |
- CERTCertificate *cert = NULL; |
- PRExplodedTime printableTime; |
- PRTime now, after; |
+static CERTCertificate *MakeV1Cert(CERTCertDBHandle *handle, |
+ CERTCertificateRequest *req, |
+ char *issuerNickName, PRBool selfsign, |
+ unsigned int serialNumber, int warpmonths, |
+ int validityMonths) { |
+ CERTCertificate *issuerCert = NULL; |
+ CERTValidity *validity; |
+ CERTCertificate *cert = NULL; |
+ PRExplodedTime printableTime; |
+ PRTime now, after; |
- if ( !selfsign ) { |
- issuerCert = CERT_FindCertByNicknameOrEmailAddr(handle, issuerNickName); |
- if (!issuerCert) { |
- SECU_PrintError(progName, "could not find certificate named \"%s\"", |
- issuerNickName); |
- return NULL; |
- } |
+ if (!selfsign) { |
+ issuerCert = CERT_FindCertByNicknameOrEmailAddr(handle, issuerNickName); |
+ if (!issuerCert) { |
+ SECU_PrintError(progName, "could not find certificate named \"%s\"", |
+ issuerNickName); |
+ return NULL; |
+ } |
+ } |
+ |
+ now = PR_Now(); |
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime); |
+ if (warpmonths) { |
+ printableTime.tm_month += warpmonths; |
+ now = PR_ImplodeTime(&printableTime); |
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime); |
+ } |
+ printableTime.tm_month += validityMonths; |
+ after = PR_ImplodeTime(&printableTime); |
+ |
+ /* note that the time is now in micro-second unit */ |
+ validity = CERT_CreateValidity(now, after); |
+ if (validity) { |
+ cert = CERT_CreateCertificate( |
+ serialNumber, (selfsign ? &req->subject : &issuerCert->subject), |
+ validity, req); |
+ |
+ CERT_DestroyValidity(validity); |
+ } |
+ if (issuerCert) { |
+ CERT_DestroyCertificate(issuerCert); |
+ } |
+ |
+ return (cert); |
+} |
+ |
+static SECStatus SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, |
+ PRBool selfsign, SECOidTag hashAlgTag, |
+ SECKEYPrivateKey *privKey, char *issuerNickName, |
+ int certVersion, void *pwarg) { |
+ SECItem der; |
+ SECKEYPrivateKey *caPrivateKey = NULL; |
+ SECStatus rv; |
+ PLArenaPool *arena; |
+ SECOidTag algID; |
+ void *dummy; |
+ |
+ if (!selfsign) { |
+ CERTCertificate *issuer = PK11_FindCertFromNickname(issuerNickName, pwarg); |
+ if ((CERTCertificate *)NULL == issuer) { |
+ SECU_PrintError(progName, "unable to find issuer with nickname %s", |
+ issuerNickName); |
+ return SECFailure; |
} |
- now = PR_Now(); |
- PR_ExplodeTime (now, PR_GMTParameters, &printableTime); |
- if ( warpmonths ) { |
- printableTime.tm_month += warpmonths; |
- now = PR_ImplodeTime (&printableTime); |
- PR_ExplodeTime (now, PR_GMTParameters, &printableTime); |
+ privKey = caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg); |
+ CERT_DestroyCertificate(issuer); |
+ if (caPrivateKey == NULL) { |
+ SECU_PrintError(progName, "unable to retrieve key %s", issuerNickName); |
+ return SECFailure; |
} |
- printableTime.tm_month += validityMonths; |
- after = PR_ImplodeTime (&printableTime); |
+ } |
- /* note that the time is now in micro-second unit */ |
- validity = CERT_CreateValidity (now, after); |
- if (validity) { |
- cert = CERT_CreateCertificate(serialNumber, |
- (selfsign ? &req->subject |
- : &issuerCert->subject), |
- validity, req); |
- |
- CERT_DestroyValidity(validity); |
- } |
- if ( issuerCert ) { |
- CERT_DestroyCertificate (issuerCert); |
- } |
- |
- return(cert); |
+ arena = cert->arena; |
+ |
+ algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlgTag); |
+ if (algID == SEC_OID_UNKNOWN) { |
+ fprintf(stderr, "Unknown key or hash type for issuer."); |
+ rv = SECFailure; |
+ goto done; |
+ } |
+ |
+ rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0); |
+ if (rv != SECSuccess) { |
+ fprintf(stderr, "Could not set signature algorithm id."); |
+ goto done; |
+ } |
+ |
+ 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; |
+ dummy = SEC_ASN1EncodeItem(arena, &der, cert, |
+ SEC_ASN1_GET(CERT_CertificateTemplate)); |
+ if (!dummy) { |
+ fprintf(stderr, "Could not encode certificate.\n"); |
+ rv = SECFailure; |
+ goto done; |
+ } |
+ |
+ rv = |
+ SEC_DerSignData(arena, &cert->derCert, der.data, der.len, privKey, algID); |
+ if (rv != SECSuccess) { |
+ fprintf(stderr, "Could not sign encoded certificate data.\n"); |
+ /* result allocated out of the arena, it will be freed |
+ * when the arena is freed */ |
+ goto done; |
+ } |
+done: |
+ if (caPrivateKey) { |
+ SECKEY_DestroyPrivateKey(caPrivateKey); |
+ } |
+ return rv; |
} |
-static SECStatus |
-SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, |
- SECOidTag hashAlgTag, |
- SECKEYPrivateKey *privKey, char *issuerNickName, |
- int certVersion, void *pwarg) |
-{ |
- SECItem der; |
- SECKEYPrivateKey *caPrivateKey = NULL; |
- SECStatus rv; |
- PLArenaPool *arena; |
- SECOidTag algID; |
- void *dummy; |
+static SECStatus CreateCert(CERTCertDBHandle *handle, PK11SlotInfo *slot, |
+ char *issuerNickName, const SECItem *certReqDER, |
+ SECKEYPrivateKey **selfsignprivkey, void *pwarg, |
+ SECOidTag hashAlgTag, unsigned int serialNumber, |
+ int warpmonths, int validityMonths, |
+ const char *emailAddrs, const char *dnsNames, |
+ PRBool ascii, PRBool selfsign, |
+ certutilExtnList extnList, const char *extGeneric, |
+ int certVersion, SECItem *certDER) { |
+ void *extHandle; |
+ CERTCertificate *subjectCert = NULL; |
+ CERTCertificateRequest *certReq = NULL; |
+ SECStatus rv = SECSuccess; |
+ CERTCertExtension **CRexts; |
- if( !selfsign ) { |
- CERTCertificate *issuer = PK11_FindCertFromNickname(issuerNickName, pwarg); |
- if( (CERTCertificate *)NULL == issuer ) { |
- SECU_PrintError(progName, "unable to find issuer with nickname %s", |
- issuerNickName); |
- return SECFailure; |
- } |
+ do { |
+ /* Create a certrequest object from the input cert request der */ |
+ certReq = GetCertRequest(certReqDER); |
+ if (certReq == NULL) { |
+ GEN_BREAK(SECFailure) |
+ } |
- privKey = caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg); |
- CERT_DestroyCertificate(issuer); |
- if (caPrivateKey == NULL) { |
- SECU_PrintError(progName, "unable to retrieve key %s", issuerNickName); |
- return SECFailure; |
+ subjectCert = MakeV1Cert(handle, certReq, issuerNickName, selfsign, |
+ serialNumber, warpmonths, validityMonths); |
+ if (subjectCert == NULL) { |
+ GEN_BREAK(SECFailure) |
+ } |
+ |
+ extHandle = CERT_StartCertExtensions(subjectCert); |
+ if (extHandle == NULL) { |
+ GEN_BREAK(SECFailure) |
+ } |
+ |
+ rv = AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric); |
+ if (rv != SECSuccess) { |
+ GEN_BREAK(SECFailure) |
+ } |
+ |
+ if (certReq->attributes != NULL && certReq->attributes[0] != NULL && |
+ certReq->attributes[0]->attrType.data != NULL && |
+ certReq->attributes[0]->attrType.len > 0 && |
+ SECOID_FindOIDTag(&certReq->attributes[0]->attrType) == |
+ SEC_OID_PKCS9_EXTENSION_REQUEST) { |
+ rv = CERT_GetCertificateRequestExtensions(certReq, &CRexts); |
+ if (rv != SECSuccess) break; |
+ rv = CERT_MergeExtensions(extHandle, CRexts); |
+ if (rv != SECSuccess) break; |
+ } |
+ |
+ CERT_FinishExtensions(extHandle); |
+ |
+ /* self-signing a cert request, find the private key */ |
+ if (selfsign && *selfsignprivkey == NULL) { |
+ *selfsignprivkey = PK11_FindKeyByDERCert(slot, subjectCert, pwarg); |
+ if (!*selfsignprivkey) { |
+ fprintf(stderr, "Failed to locate private key.\n"); |
+ rv = SECFailure; |
+ break; |
} |
} |
- |
- arena = cert->arena; |
- algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlgTag); |
- if (algID == SEC_OID_UNKNOWN) { |
- fprintf(stderr, "Unknown key or hash type for issuer."); |
- rv = SECFailure; |
- goto done; |
+ rv = SignCert(handle, subjectCert, selfsign, hashAlgTag, *selfsignprivkey, |
+ issuerNickName, certVersion, pwarg); |
+ if (rv != SECSuccess) break; |
+ |
+ rv = SECFailure; |
+ if (ascii) { |
+ char *asciiDER = |
+ BTOA_DataToAscii(subjectCert->derCert.data, subjectCert->derCert.len); |
+ if (asciiDER) { |
+ char *wrapped = PR_smprintf("%s\n%s\n%s\n", NS_CERT_HEADER, asciiDER, |
+ NS_CERT_TRAILER); |
+ if (wrapped) { |
+ PRUint32 wrappedLen = PL_strlen(wrapped); |
+ if (SECITEM_AllocItem(NULL, certDER, wrappedLen)) { |
+ PORT_Memcpy(certDER->data, wrapped, wrappedLen); |
+ rv = SECSuccess; |
+ } |
+ PR_smprintf_free(wrapped); |
+ } |
+ PORT_Free(asciiDER); |
+ } |
+ } else { |
+ rv = SECITEM_CopyItem(NULL, certDER, &subjectCert->derCert); |
} |
- |
- rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0); |
- if (rv != SECSuccess) { |
- fprintf(stderr, "Could not set signature algorithm id."); |
- goto done; |
- } |
- |
- 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; |
- dummy = SEC_ASN1EncodeItem (arena, &der, cert, |
- SEC_ASN1_GET(CERT_CertificateTemplate)); |
- if (!dummy) { |
- fprintf (stderr, "Could not encode certificate.\n"); |
- rv = SECFailure; |
- goto done; |
- } |
- |
- rv = SEC_DerSignData(arena, &cert->derCert, der.data, der.len, privKey, algID); |
- if (rv != SECSuccess) { |
- fprintf (stderr, "Could not sign encoded certificate data.\n"); |
- /* result allocated out of the arena, it will be freed |
- * when the arena is freed */ |
- goto done; |
- } |
-done: |
- if (caPrivateKey) { |
- SECKEY_DestroyPrivateKey(caPrivateKey); |
- } |
- return rv; |
+ } while (0); |
+ CERT_DestroyCertificateRequest(certReq); |
+ CERT_DestroyCertificate(subjectCert); |
+ if (rv != SECSuccess) { |
+ PRErrorCode perr = PR_GetError(); |
+ fprintf(stderr, "%s: unable to create cert (%s)\n", progName, |
+ SECU_Strerror(perr)); |
+ } |
+ return (rv); |
} |
-static SECStatus |
-CreateCert( |
- CERTCertDBHandle *handle, |
- PK11SlotInfo *slot, |
- char * issuerNickName, |
- const SECItem * certReqDER, |
- SECKEYPrivateKey **selfsignprivkey, |
- void *pwarg, |
- SECOidTag hashAlgTag, |
- unsigned int serialNumber, |
- int warpmonths, |
- int validityMonths, |
- const char *emailAddrs, |
- const char *dnsNames, |
- PRBool ascii, |
- PRBool selfsign, |
- certutilExtnList extnList, |
- const char *extGeneric, |
- int certVersion, |
- SECItem * certDER) |
-{ |
- void * extHandle; |
- CERTCertificate *subjectCert = NULL; |
- CERTCertificateRequest *certReq = NULL; |
- SECStatus rv = SECSuccess; |
- CERTCertExtension **CRexts; |
- |
- do { |
- /* Create a certrequest object from the input cert request der */ |
- certReq = GetCertRequest(certReqDER); |
- if (certReq == NULL) { |
- GEN_BREAK (SECFailure) |
- } |
- |
- subjectCert = MakeV1Cert (handle, certReq, issuerNickName, selfsign, |
- serialNumber, warpmonths, validityMonths); |
- if (subjectCert == NULL) { |
- GEN_BREAK (SECFailure) |
- } |
- |
- |
- extHandle = CERT_StartCertExtensions (subjectCert); |
- if (extHandle == NULL) { |
- GEN_BREAK (SECFailure) |
- } |
- |
- rv = AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric); |
- if (rv != SECSuccess) { |
- GEN_BREAK (SECFailure) |
- } |
- |
- if (certReq->attributes != NULL && |
- certReq->attributes[0] != NULL && |
- certReq->attributes[0]->attrType.data != NULL && |
- certReq->attributes[0]->attrType.len > 0 && |
- SECOID_FindOIDTag(&certReq->attributes[0]->attrType) |
- == SEC_OID_PKCS9_EXTENSION_REQUEST) { |
- rv = CERT_GetCertificateRequestExtensions(certReq, &CRexts); |
- if (rv != SECSuccess) |
- break; |
- rv = CERT_MergeExtensions(extHandle, CRexts); |
- if (rv != SECSuccess) |
- break; |
- } |
- |
- CERT_FinishExtensions(extHandle); |
- |
- /* self-signing a cert request, find the private key */ |
- if (selfsign && *selfsignprivkey == NULL) { |
- *selfsignprivkey = PK11_FindKeyByDERCert(slot, subjectCert, pwarg); |
- if (!*selfsignprivkey) { |
- fprintf(stderr, "Failed to locate private key.\n"); |
- rv = SECFailure; |
- break; |
- } |
- } |
- |
- rv = SignCert(handle, subjectCert, selfsign, hashAlgTag, |
- *selfsignprivkey, issuerNickName, |
- certVersion, pwarg); |
- if (rv != SECSuccess) |
- break; |
- |
- rv = SECFailure; |
- if (ascii) { |
- char * asciiDER = BTOA_DataToAscii(subjectCert->derCert.data, |
- subjectCert->derCert.len); |
- if (asciiDER) { |
- char * wrapped = PR_smprintf("%s\n%s\n%s\n", |
- NS_CERT_HEADER, |
- asciiDER, |
- NS_CERT_TRAILER); |
- if (wrapped) { |
- PRUint32 wrappedLen = PL_strlen(wrapped); |
- if (SECITEM_AllocItem(NULL, certDER, wrappedLen)) { |
- PORT_Memcpy(certDER->data, wrapped, wrappedLen); |
- rv = SECSuccess; |
- } |
- PR_smprintf_free(wrapped); |
- } |
- PORT_Free(asciiDER); |
- } |
- } else { |
- rv = SECITEM_CopyItem(NULL, certDER, &subjectCert->derCert); |
- } |
- } while (0); |
- CERT_DestroyCertificateRequest (certReq); |
- CERT_DestroyCertificate (subjectCert); |
- if (rv != SECSuccess) { |
- PRErrorCode perr = PR_GetError(); |
- fprintf(stderr, "%s: unable to create cert (%s)\n", progName, |
- SECU_Strerror(perr)); |
- } |
- return (rv); |
-} |
- |
- |
/* |
* map a class to a user presentable string |
*/ |
static const char *objClassArray[] = { |
- "Data", |
- "Certificate", |
- "Public Key", |
- "Private Key", |
- "Secret Key", |
- "Hardware Feature", |
- "Domain Parameters", |
- "Mechanism" |
-}; |
+ "Data", "Certificate", "Public Key", "Private Key", |
+ "Secret Key", "Hardware Feature", "Domain Parameters", "Mechanism"}; |
static const char *objNSSClassArray[] = { |
- "CKO_NSS", |
- "Crl", |
- "SMIME Record", |
- "Trust", |
- "Builtin Root List" |
-}; |
+ "CKO_NSS", "Crl", "SMIME Record", "Trust", "Builtin Root List"}; |
+const char *getObjectClass(CK_ULONG classType) { |
+ static char buf[sizeof(CK_ULONG) * 2 + 3]; |
-const char * |
-getObjectClass(CK_ULONG classType) |
-{ |
- static char buf[sizeof(CK_ULONG)*2+3]; |
- |
- if (classType <= CKO_MECHANISM) { |
- return objClassArray[classType]; |
- } |
- if (classType >= CKO_NSS && classType <= CKO_NSS_BUILTIN_ROOT_LIST) { |
- return objNSSClassArray[classType - CKO_NSS]; |
- } |
- sprintf(buf, "0x%lx", classType); |
- return buf; |
+ if (classType <= CKO_MECHANISM) { |
+ return objClassArray[classType]; |
+ } |
+ if (classType >= CKO_NSS && classType <= CKO_NSS_BUILTIN_ROOT_LIST) { |
+ return objNSSClassArray[classType - CKO_NSS]; |
+ } |
+ sprintf(buf, "0x%lx", classType); |
+ return buf; |
} |
typedef struct { |
- char *name; |
- int nameSize; |
- CK_ULONG value; |
+ char *name; |
+ int nameSize; |
+ CK_ULONG value; |
} flagArray; |
-#define NAME_SIZE(x) #x,sizeof(#x)-1 |
+#define NAME_SIZE(x) #x, sizeof(#x) - 1 |
-flagArray opFlagsArray[] = |
-{ |
- {NAME_SIZE(encrypt), CKF_ENCRYPT}, |
- {NAME_SIZE(decrypt), CKF_DECRYPT}, |
- {NAME_SIZE(sign), CKF_SIGN}, |
- {NAME_SIZE(sign_recover), CKF_SIGN_RECOVER}, |
- {NAME_SIZE(verify), CKF_VERIFY}, |
- {NAME_SIZE(verify_recover), CKF_VERIFY_RECOVER}, |
- {NAME_SIZE(wrap), CKF_WRAP}, |
- {NAME_SIZE(unwrap), CKF_UNWRAP}, |
- {NAME_SIZE(derive), CKF_DERIVE}, |
-}; |
+flagArray opFlagsArray[] = {{NAME_SIZE(encrypt), CKF_ENCRYPT}, |
+ {NAME_SIZE(decrypt), CKF_DECRYPT}, |
+ {NAME_SIZE(sign), CKF_SIGN}, |
+ {NAME_SIZE(sign_recover), CKF_SIGN_RECOVER}, |
+ {NAME_SIZE(verify), CKF_VERIFY}, |
+ {NAME_SIZE(verify_recover), CKF_VERIFY_RECOVER}, |
+ {NAME_SIZE(wrap), CKF_WRAP}, |
+ {NAME_SIZE(unwrap), CKF_UNWRAP}, |
+ {NAME_SIZE(derive), CKF_DERIVE}, }; |
-int opFlagsCount = sizeof(opFlagsArray)/sizeof(flagArray); |
+int opFlagsCount = sizeof(opFlagsArray) / sizeof(flagArray); |
-flagArray attrFlagsArray[] = |
-{ |
+flagArray attrFlagsArray[] = { |
{NAME_SIZE(token), PK11_ATTR_TOKEN}, |
{NAME_SIZE(session), PK11_ATTR_SESSION}, |
{NAME_SIZE(private), PK11_ATTR_PRIVATE}, |
{NAME_SIZE(public), PK11_ATTR_PUBLIC}, |
{NAME_SIZE(modifiable), PK11_ATTR_MODIFIABLE}, |
{NAME_SIZE(unmodifiable), PK11_ATTR_UNMODIFIABLE}, |
{NAME_SIZE(sensitive), PK11_ATTR_SENSITIVE}, |
{NAME_SIZE(insensitive), PK11_ATTR_INSENSITIVE}, |
{NAME_SIZE(extractable), PK11_ATTR_EXTRACTABLE}, |
- {NAME_SIZE(unextractable), PK11_ATTR_UNEXTRACTABLE} |
+ {NAME_SIZE(unextractable), PK11_ATTR_UNEXTRACTABLE}}; |
-}; |
- |
-int attrFlagsCount = sizeof(attrFlagsArray)/sizeof(flagArray); |
+int attrFlagsCount = sizeof(attrFlagsArray) / sizeof(flagArray); |
#define MAX_STRING 30 |
CK_ULONG |
-GetFlags(char *flagsString, flagArray *flagArray, int count) |
-{ |
- CK_ULONG flagsValue = strtol(flagsString, NULL, 0); |
- int i; |
+GetFlags(char *flagsString, flagArray *flagArray, int count) { |
+ CK_ULONG flagsValue = strtol(flagsString, NULL, 0); |
+ int i; |
- if ((flagsValue != 0) || (*flagsString == 0)) { |
- return flagsValue; |
- } |
- while (*flagsString) { |
- for (i=0; i < count; i++) { |
- if (strncmp(flagsString, flagArray[i].name, flagArray[i].nameSize) |
- == 0) { |
- flagsValue |= flagArray[i].value; |
- flagsString += flagArray[i].nameSize; |
- if (*flagsString != 0) { |
- flagsString++; |
- } |
- break; |
- } |
- } |
- if (i == count) { |
- char name[MAX_STRING]; |
- char *tok; |
+ if ((flagsValue != 0) || (*flagsString == 0)) { |
+ return flagsValue; |
+ } |
+ while (*flagsString) { |
+ for (i = 0; i < count; i++) { |
+ if (strncmp(flagsString, flagArray[i].name, flagArray[i].nameSize) == 0) { |
+ flagsValue |= flagArray[i].value; |
+ flagsString += flagArray[i].nameSize; |
+ if (*flagsString != 0) { |
+ flagsString++; |
+ } |
+ break; |
+ } |
+ } |
+ if (i == count) { |
+ char name[MAX_STRING]; |
+ char *tok; |
- strncpy(name,flagsString, MAX_STRING); |
- name[MAX_STRING-1] = 0; |
- tok = strchr(name, ','); |
- if (tok) { |
- *tok = 0; |
- } |
- fprintf(stderr,"Unknown flag (%s)\n",name); |
- tok = strchr(flagsString, ','); |
- if (tok == NULL) { |
- break; |
- } |
- flagsString = tok+1; |
- } |
+ strncpy(name, flagsString, MAX_STRING); |
+ name[MAX_STRING - 1] = 0; |
+ tok = strchr(name, ','); |
+ if (tok) { |
+ *tok = 0; |
+ } |
+ fprintf(stderr, "Unknown flag (%s)\n", name); |
+ tok = strchr(flagsString, ','); |
+ if (tok == NULL) { |
+ break; |
+ } |
+ flagsString = tok + 1; |
} |
- return flagsValue; |
+ } |
+ return flagsValue; |
} |
CK_FLAGS |
-GetOpFlags(char *flags) |
-{ |
- return GetFlags(flags, opFlagsArray, opFlagsCount); |
+GetOpFlags(char *flags) { return GetFlags(flags, opFlagsArray, opFlagsCount); } |
+ |
+PK11AttrFlags GetAttrFlags(char *flags) { |
+ return GetFlags(flags, attrFlagsArray, attrFlagsCount); |
} |
-PK11AttrFlags |
-GetAttrFlags(char *flags) |
-{ |
- return GetFlags(flags, attrFlagsArray, attrFlagsCount); |
-} |
- |
-char *mkNickname(unsigned char *data, int len) |
-{ |
- char *nick = PORT_Alloc(len+1); |
- if (!nick) { |
- return nick; |
- } |
- PORT_Memcpy(nick, data, len); |
- nick[len] = 0; |
- return nick; |
+char *mkNickname(unsigned char *data, int len) { |
+ char *nick = PORT_Alloc(len + 1); |
+ if (!nick) { |
+ return nick; |
+ } |
+ PORT_Memcpy(nick, data, len); |
+ nick[len] = 0; |
+ return nick; |
} |
/* |
* dump a PK11_MergeTokens error log to the console |
*/ |
-void |
-DumpMergeLog(const char *progname, PK11MergeLog *log) |
-{ |
- PK11MergeLogNode *node; |
+void DumpMergeLog(const char *progname, PK11MergeLog *log) { |
+ PK11MergeLogNode *node; |
- for (node = log->head; node; node = node->next) { |
- SECItem attrItem; |
- char *nickname = NULL; |
- const char *objectClass = NULL; |
- SECStatus rv; |
+ for (node = log->head; node; node = node->next) { |
+ SECItem attrItem; |
+ char *nickname = NULL; |
+ const char *objectClass = NULL; |
+ SECStatus rv; |
- attrItem.data = NULL; |
- rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object, |
- CKA_LABEL, &attrItem); |
- if (rv == SECSuccess) { |
- nickname = mkNickname(attrItem.data, attrItem.len); |
- PORT_Free(attrItem.data); |
- } |
- attrItem.data = NULL; |
- rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object, |
- CKA_CLASS, &attrItem); |
- if (rv == SECSuccess) { |
- if (attrItem.len == sizeof(CK_ULONG)) { |
- objectClass = getObjectClass(*(CK_ULONG *)attrItem.data); |
- } |
- PORT_Free(attrItem.data); |
- } |
+ attrItem.data = NULL; |
+ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object, CKA_LABEL, |
+ &attrItem); |
+ if (rv == SECSuccess) { |
+ nickname = mkNickname(attrItem.data, attrItem.len); |
+ PORT_Free(attrItem.data); |
+ } |
+ attrItem.data = NULL; |
+ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object, CKA_CLASS, |
+ &attrItem); |
+ if (rv == SECSuccess) { |
+ if (attrItem.len == sizeof(CK_ULONG)) { |
+ objectClass = getObjectClass(*(CK_ULONG *)attrItem.data); |
+ } |
+ PORT_Free(attrItem.data); |
+ } |
- fprintf(stderr, "%s: Could not merge object %s (type %s): %s\n", |
- progName, |
- nickname ? nickname : "unnamed", |
- objectClass ? objectClass : "unknown", |
- SECU_Strerror(node->error)); |
+ fprintf(stderr, "%s: Could not merge object %s (type %s): %s\n", progName, |
+ nickname ? nickname : "unnamed", |
+ objectClass ? objectClass : "unknown", SECU_Strerror(node->error)); |
- if (nickname) { |
- PORT_Free(nickname); |
- } |
+ if (nickname) { |
+ PORT_Free(nickname); |
} |
+ } |
} |
/* Certutil commands */ |
enum { |
- cmd_AddCert = 0, |
- cmd_CreateNewCert, |
- cmd_DeleteCert, |
- cmd_AddEmailCert, |
- cmd_DeleteKey, |
- cmd_GenKeyPair, |
- cmd_PrintHelp, |
- cmd_PrintSyntax, |
- cmd_ListKeys, |
- cmd_ListCerts, |
- cmd_ModifyCertTrust, |
- cmd_NewDBs, |
- cmd_DumpChain, |
- cmd_CertReq, |
- cmd_CreateAndAddCert, |
- cmd_TokenReset, |
- cmd_ListModules, |
- cmd_CheckCertValidity, |
- cmd_ChangePassword, |
- cmd_Version, |
- cmd_Batch, |
- cmd_Merge, |
- cmd_UpgradeMerge, /* test only */ |
- max_cmd |
+ cmd_AddCert = 0, |
+ cmd_CreateNewCert, |
+ cmd_DeleteCert, |
+ cmd_AddEmailCert, |
+ cmd_DeleteKey, |
+ cmd_GenKeyPair, |
+ cmd_PrintHelp, |
+ cmd_PrintSyntax, |
+ cmd_ListKeys, |
+ cmd_ListCerts, |
+ cmd_ModifyCertTrust, |
+ cmd_NewDBs, |
+ cmd_DumpChain, |
+ cmd_CertReq, |
+ cmd_CreateAndAddCert, |
+ cmd_TokenReset, |
+ cmd_ListModules, |
+ cmd_CheckCertValidity, |
+ cmd_ChangePassword, |
+ cmd_Version, |
+ cmd_Batch, |
+ cmd_Merge, |
+ cmd_UpgradeMerge, /* test only */ |
+ max_cmd |
}; |
/* Certutil options */ |
enum certutilOpts { |
- opt_SSOPass = 0, |
- opt_AddKeyUsageExt, |
- opt_AddBasicConstraintExt, |
- opt_AddAuthorityKeyIDExt, |
- opt_AddCRLDistPtsExt, |
- opt_AddNSCertTypeExt, |
- opt_AddExtKeyUsageExt, |
- opt_ExtendedEmailAddrs, |
- opt_ExtendedDNSNames, |
- opt_ASCIIForIO, |
- opt_ValidityTime, |
- opt_IssuerName, |
- opt_CertDir, |
- opt_VerifySig, |
- opt_PasswordFile, |
- opt_KeySize, |
- opt_TokenName, |
- opt_InputFile, |
- opt_Emailaddress, |
- opt_KeyIndex, |
- opt_KeyType, |
- opt_DetailedInfo, |
- opt_SerialNumber, |
- opt_Nickname, |
- opt_OutputFile, |
- opt_PhoneNumber, |
- opt_DBPrefix, |
- opt_PQGFile, |
- opt_BinaryDER, |
- opt_Subject, |
- opt_Trust, |
- opt_Usage, |
- opt_Validity, |
- opt_OffsetMonths, |
- opt_SelfSign, |
- opt_RW, |
- opt_Exponent, |
- opt_NoiseFile, |
- opt_Hash, |
- opt_NewPasswordFile, |
- opt_AddAuthInfoAccExt, |
- opt_AddSubjInfoAccExt, |
- opt_AddCertPoliciesExt, |
- opt_AddPolicyMapExt, |
- opt_AddPolicyConstrExt, |
- opt_AddInhibAnyExt, |
- opt_AddNameConstraintsExt, |
- opt_AddSubjectKeyIDExt, |
- opt_AddCmdKeyUsageExt, |
- opt_AddCmdNSCertTypeExt, |
- opt_AddCmdExtKeyUsageExt, |
- opt_SourceDir, |
- opt_SourcePrefix, |
- opt_UpgradeID, |
- opt_UpgradeTokenName, |
- opt_KeyOpFlagsOn, |
- opt_KeyOpFlagsOff, |
- opt_KeyAttrFlags, |
- opt_EmptyPassword, |
- opt_CertVersion, |
- opt_AddSubjectAltNameExt, |
- opt_DumpExtensionValue, |
- opt_GenericExtensions, |
- opt_Help |
+ opt_SSOPass = 0, |
+ opt_AddKeyUsageExt, |
+ opt_AddBasicConstraintExt, |
+ opt_AddAuthorityKeyIDExt, |
+ opt_AddCRLDistPtsExt, |
+ opt_AddNSCertTypeExt, |
+ opt_AddExtKeyUsageExt, |
+ opt_ExtendedEmailAddrs, |
+ opt_ExtendedDNSNames, |
+ opt_ASCIIForIO, |
+ opt_ValidityTime, |
+ opt_IssuerName, |
+ opt_CertDir, |
+ opt_VerifySig, |
+ opt_PasswordFile, |
+ opt_KeySize, |
+ opt_TokenName, |
+ opt_InputFile, |
+ opt_Emailaddress, |
+ opt_KeyIndex, |
+ opt_KeyType, |
+ opt_DetailedInfo, |
+ opt_SerialNumber, |
+ opt_Nickname, |
+ opt_OutputFile, |
+ opt_PhoneNumber, |
+ opt_DBPrefix, |
+ opt_PQGFile, |
+ opt_BinaryDER, |
+ opt_Subject, |
+ opt_Trust, |
+ opt_Usage, |
+ opt_Validity, |
+ opt_OffsetMonths, |
+ opt_SelfSign, |
+ opt_RW, |
+ opt_Exponent, |
+ opt_NoiseFile, |
+ opt_Hash, |
+ opt_NewPasswordFile, |
+ opt_AddAuthInfoAccExt, |
+ opt_AddSubjInfoAccExt, |
+ opt_AddCertPoliciesExt, |
+ opt_AddPolicyMapExt, |
+ opt_AddPolicyConstrExt, |
+ opt_AddInhibAnyExt, |
+ opt_AddNameConstraintsExt, |
+ opt_AddSubjectKeyIDExt, |
+ opt_AddCmdKeyUsageExt, |
+ opt_AddCmdNSCertTypeExt, |
+ opt_AddCmdExtKeyUsageExt, |
+ opt_SourceDir, |
+ opt_SourcePrefix, |
+ opt_UpgradeID, |
+ opt_UpgradeTokenName, |
+ opt_KeyOpFlagsOn, |
+ opt_KeyOpFlagsOff, |
+ opt_KeyAttrFlags, |
+ opt_EmptyPassword, |
+ opt_CertVersion, |
+ opt_AddSubjectAltNameExt, |
+ opt_DumpExtensionValue, |
+ opt_GenericExtensions, |
+ opt_Help |
}; |
-static const |
-secuCommandFlag commands_init[] = |
-{ |
- { /* cmd_AddCert */ 'A', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_CreateNewCert */ 'C', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_DeleteCert */ 'D', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_AddEmailCert */ 'E', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_DeleteKey */ 'F', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_GenKeyPair */ 'G', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_PrintHelp */ 'H', PR_FALSE, 0, PR_FALSE, "help" }, |
- { /* cmd_PrintSyntax */ 0, PR_FALSE, 0, PR_FALSE, |
- "syntax" }, |
- { /* cmd_ListKeys */ 'K', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_ListCerts */ 'L', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_ModifyCertTrust */ 'M', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_NewDBs */ 'N', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_DumpChain */ 'O', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_CertReq */ 'R', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_CreateAndAddCert */ 'S', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_TokenReset */ 'T', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_ListModules */ 'U', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_CheckCertValidity */ 'V', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_ChangePassword */ 'W', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_Version */ 'Y', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_Batch */ 'B', PR_FALSE, 0, PR_FALSE }, |
- { /* cmd_Merge */ 0, PR_FALSE, 0, PR_FALSE, "merge" }, |
- { /* cmd_UpgradeMerge */ 0, PR_FALSE, 0, PR_FALSE, |
- "upgrade-merge" } |
-}; |
+static const secuCommandFlag commands_init[] = { |
+ {/* cmd_AddCert */ 'A', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_CreateNewCert */ 'C', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_DeleteCert */ 'D', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_AddEmailCert */ 'E', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_DeleteKey */ 'F', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_GenKeyPair */ 'G', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_PrintHelp */ 'H', PR_FALSE, 0, PR_FALSE, "help"}, |
+ {/* cmd_PrintSyntax */ 0, PR_FALSE, 0, PR_FALSE, "syntax"}, |
+ {/* cmd_ListKeys */ 'K', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_ListCerts */ 'L', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_ModifyCertTrust */ 'M', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_NewDBs */ 'N', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_DumpChain */ 'O', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_CertReq */ 'R', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_CreateAndAddCert */ 'S', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_TokenReset */ 'T', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_ListModules */ 'U', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_CheckCertValidity */ 'V', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_ChangePassword */ 'W', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_Version */ 'Y', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_Batch */ 'B', PR_FALSE, 0, PR_FALSE}, |
+ {/* cmd_Merge */ 0, PR_FALSE, 0, PR_FALSE, "merge"}, |
+ {/* cmd_UpgradeMerge */ 0, PR_FALSE, 0, PR_FALSE, "upgrade-merge"}}; |
#define NUM_COMMANDS ((sizeof commands_init) / (sizeof commands_init[0])) |
- |
-static const |
-secuCommandFlag options_init[] = |
-{ |
- { /* opt_SSOPass */ '0', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_AddKeyUsageExt */ '1', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_AddBasicConstraintExt*/ '2', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_AddAuthorityKeyIDExt*/ '3', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_AddCRLDistPtsExt */ '4', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_AddNSCertTypeExt */ '5', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_AddExtKeyUsageExt */ '6', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_ExtendedEmailAddrs */ '7', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_ExtendedDNSNames */ '8', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_ASCIIForIO */ 'a', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_ValidityTime */ 'b', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_IssuerName */ 'c', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_VerifySig */ 'e', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_PasswordFile */ 'f', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_InputFile */ 'i', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_Emailaddress */ 0, PR_TRUE, 0, PR_FALSE, "email" }, |
- { /* opt_KeyIndex */ 'j', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_KeyType */ 'k', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_DetailedInfo */ 'l', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_SerialNumber */ 'm', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_OutputFile */ 'o', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_PhoneNumber */ 'p', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_PQGFile */ 'q', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_BinaryDER */ 'r', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_Subject */ 's', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_Usage */ 'u', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_Validity */ 'v', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_OffsetMonths */ 'w', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_SelfSign */ 'x', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_RW */ 'X', PR_FALSE, 0, PR_FALSE }, |
- { /* opt_Exponent */ 'y', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_Hash */ 'Z', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_NewPasswordFile */ '@', PR_TRUE, 0, PR_FALSE }, |
- { /* opt_AddAuthInfoAccExt */ 0, PR_FALSE, 0, PR_FALSE, "extAIA" }, |
- { /* opt_AddSubjInfoAccExt */ 0, PR_FALSE, 0, PR_FALSE, "extSIA" }, |
- { /* opt_AddCertPoliciesExt */ 0, PR_FALSE, 0, PR_FALSE, "extCP" }, |
- { /* opt_AddPolicyMapExt */ 0, PR_FALSE, 0, PR_FALSE, "extPM" }, |
- { /* opt_AddPolicyConstrExt */ 0, PR_FALSE, 0, PR_FALSE, "extPC" }, |
- { /* opt_AddInhibAnyExt */ 0, PR_FALSE, 0, PR_FALSE, "extIA" }, |
- { /* opt_AddNameConstraintsExt*/ 0, PR_FALSE, 0, PR_FALSE, "extNC" }, |
- { /* opt_AddSubjectKeyIDExt */ 0, PR_FALSE, 0, PR_FALSE, |
- "extSKID" }, |
- { /* opt_AddCmdKeyUsageExt */ 0, PR_TRUE, 0, PR_FALSE, |
- "keyUsage" }, |
- { /* opt_AddCmdNSCertTypeExt */ 0, PR_TRUE, 0, PR_FALSE, |
- "nsCertType" }, |
- { /* opt_AddCmdExtKeyUsageExt*/ 0, PR_TRUE, 0, PR_FALSE, |
- "extKeyUsage" }, |
- { /* opt_SourceDir */ 0, PR_TRUE, 0, PR_FALSE, |
- "source-dir"}, |
- { /* opt_SourcePrefix */ 0, PR_TRUE, 0, PR_FALSE, |
- "source-prefix"}, |
- { /* opt_UpgradeID */ 0, PR_TRUE, 0, PR_FALSE, |
- "upgrade-id"}, |
- { /* opt_UpgradeTokenName */ 0, PR_TRUE, 0, PR_FALSE, |
- "upgrade-token-name"}, |
- { /* opt_KeyOpFlagsOn */ 0, PR_TRUE, 0, PR_FALSE, |
- "keyOpFlagsOn"}, |
- { /* opt_KeyOpFlagsOff */ 0, PR_TRUE, 0, PR_FALSE, |
- "keyOpFlagsOff"}, |
- { /* opt_KeyAttrFlags */ 0, PR_TRUE, 0, PR_FALSE, |
- "keyAttrFlags"}, |
- { /* opt_EmptyPassword */ 0, PR_FALSE, 0, PR_FALSE, |
- "empty-password"}, |
- { /* opt_CertVersion */ 0, PR_TRUE, 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])) |
+static const secuCommandFlag options_init[] = { |
+ {/* opt_SSOPass */ '0', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_AddKeyUsageExt */ '1', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_AddBasicConstraintExt*/ '2', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_AddAuthorityKeyIDExt*/ '3', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_AddCRLDistPtsExt */ '4', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_AddNSCertTypeExt */ '5', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_AddExtKeyUsageExt */ '6', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_ExtendedEmailAddrs */ '7', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_ExtendedDNSNames */ '8', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_ASCIIForIO */ 'a', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_ValidityTime */ 'b', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_IssuerName */ 'c', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_VerifySig */ 'e', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_PasswordFile */ 'f', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_InputFile */ 'i', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_Emailaddress */ 0, PR_TRUE, 0, PR_FALSE, "email"}, |
+ {/* opt_KeyIndex */ 'j', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_KeyType */ 'k', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_DetailedInfo */ 'l', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_SerialNumber */ 'm', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_OutputFile */ 'o', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_PhoneNumber */ 'p', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_PQGFile */ 'q', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_BinaryDER */ 'r', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_Subject */ 's', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_Usage */ 'u', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_Validity */ 'v', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_OffsetMonths */ 'w', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_SelfSign */ 'x', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_RW */ 'X', PR_FALSE, 0, PR_FALSE}, |
+ {/* opt_Exponent */ 'y', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_Hash */ 'Z', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_NewPasswordFile */ '@', PR_TRUE, 0, PR_FALSE}, |
+ {/* opt_AddAuthInfoAccExt */ 0, PR_FALSE, 0, PR_FALSE, "extAIA"}, |
+ {/* opt_AddSubjInfoAccExt */ 0, PR_FALSE, 0, PR_FALSE, "extSIA"}, |
+ {/* opt_AddCertPoliciesExt */ 0, PR_FALSE, 0, PR_FALSE, "extCP"}, |
+ {/* opt_AddPolicyMapExt */ 0, PR_FALSE, 0, PR_FALSE, "extPM"}, |
+ {/* opt_AddPolicyConstrExt */ 0, PR_FALSE, 0, PR_FALSE, "extPC"}, |
+ {/* opt_AddInhibAnyExt */ 0, PR_FALSE, 0, PR_FALSE, "extIA"}, |
+ {/* opt_AddNameConstraintsExt*/ 0, PR_FALSE, 0, PR_FALSE, "extNC"}, |
+ {/* opt_AddSubjectKeyIDExt */ 0, PR_FALSE, 0, PR_FALSE, "extSKID"}, |
+ {/* opt_AddCmdKeyUsageExt */ 0, PR_TRUE, 0, PR_FALSE, "keyUsage"}, |
+ {/* opt_AddCmdNSCertTypeExt */ 0, PR_TRUE, 0, PR_FALSE, "nsCertType"}, |
+ {/* opt_AddCmdExtKeyUsageExt*/ 0, PR_TRUE, 0, PR_FALSE, "extKeyUsage"}, |
+ {/* opt_SourceDir */ 0, PR_TRUE, 0, PR_FALSE, "source-dir"}, |
+ {/* opt_SourcePrefix */ 0, PR_TRUE, 0, PR_FALSE, "source-prefix"}, |
+ {/* opt_UpgradeID */ 0, PR_TRUE, 0, PR_FALSE, "upgrade-id"}, |
+ {/* opt_UpgradeTokenName */ 0, PR_TRUE, 0, PR_FALSE, |
+ "upgrade-token-" |
+ "name"}, |
+ {/* opt_KeyOpFlagsOn */ 0, PR_TRUE, 0, PR_FALSE, "keyOpFlagsOn"}, |
+ {/* opt_KeyOpFlagsOff */ 0, PR_TRUE, 0, PR_FALSE, "keyOpFlagsOff"}, |
+ {/* opt_KeyAttrFlags */ 0, PR_TRUE, 0, PR_FALSE, "keyAttrFlags"}, |
+ {/* opt_EmptyPassword */ 0, PR_FALSE, 0, PR_FALSE, "empty-password"}, |
+ {/* opt_CertVersion */ 0, PR_TRUE, 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])) |
static secuCommandFlag certutil_commands[NUM_COMMANDS]; |
-static secuCommandFlag certutil_options [NUM_OPTIONS ]; |
+static secuCommandFlag certutil_options[NUM_OPTIONS]; |
-static const secuCommand certutil = { |
- NUM_COMMANDS, |
- NUM_OPTIONS, |
- certutil_commands, |
- certutil_options |
-}; |
+static const secuCommand certutil = {NUM_COMMANDS, NUM_OPTIONS, |
+ certutil_commands, certutil_options}; |
static certutilExtnList certutil_extns; |
-static int |
-certutil_main(int argc, char **argv, PRBool initialize) |
-{ |
- CERTCertDBHandle *certHandle; |
- PK11SlotInfo *slot = NULL; |
- CERTName * subject = 0; |
- PRFileDesc *inFile = PR_STDIN; |
- PRFileDesc *outFile = PR_STDOUT; |
- SECItem certReqDER = { siBuffer, NULL, 0 }; |
- SECItem certDER = { siBuffer, NULL, 0 }; |
- char * slotname = "internal"; |
- char * certPrefix = ""; |
- char * sourceDir = ""; |
- char * srcCertPrefix = ""; |
- char * upgradeID = ""; |
- char * upgradeTokenName = ""; |
- KeyType keytype = rsaKey; |
- char * name = NULL; |
- char * email = NULL; |
- char * keysource = NULL; |
- 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; |
- int commandsEntered = 0; |
- char commandToRun = '\0'; |
- secuPWData pwdata = { PW_NONE, 0 }; |
- secuPWData pwdata2 = { PW_NONE, 0 }; |
- PRBool readOnly = PR_FALSE; |
- PRBool initialized = PR_FALSE; |
- CK_FLAGS keyOpFlagsOn = 0; |
- CK_FLAGS keyOpFlagsOff = 0; |
- PK11AttrFlags keyAttrFlags = |
- PK11_ATTR_TOKEN | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE; |
+static int certutil_main(int argc, char **argv, PRBool initialize) { |
+ CERTCertDBHandle *certHandle; |
+ PK11SlotInfo *slot = NULL; |
+ CERTName *subject = 0; |
+ PRFileDesc *inFile = PR_STDIN; |
+ PRFileDesc *outFile = PR_STDOUT; |
+ SECItem certReqDER = {siBuffer, NULL, 0}; |
+ SECItem certDER = {siBuffer, NULL, 0}; |
+ char *slotname = "internal"; |
+ char *certPrefix = ""; |
+ char *sourceDir = ""; |
+ char *srcCertPrefix = ""; |
+ char *upgradeID = ""; |
+ char *upgradeTokenName = ""; |
+ KeyType keytype = rsaKey; |
+ char *name = NULL; |
+ char *email = NULL; |
+ char *keysource = NULL; |
+ 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; |
+ int commandsEntered = 0; |
+ char commandToRun = '\0'; |
+ secuPWData pwdata = {PW_NONE, 0}; |
+ secuPWData pwdata2 = {PW_NONE, 0}; |
+ PRBool readOnly = PR_FALSE; |
+ PRBool initialized = PR_FALSE; |
+ CK_FLAGS keyOpFlagsOn = 0; |
+ CK_FLAGS keyOpFlagsOff = 0; |
+ PK11AttrFlags keyAttrFlags = |
+ PK11_ATTR_TOKEN | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE; |
- SECKEYPrivateKey *privkey = NULL; |
- SECKEYPublicKey *pubkey = NULL; |
+ SECKEYPrivateKey *privkey = NULL; |
+ SECKEYPublicKey *pubkey = NULL; |
+ int i; |
+ SECStatus rv; |
+ |
+ progName = PORT_Strrchr(argv[0], '/'); |
+ progName = progName ? progName + 1 : argv[0]; |
+ memcpy(certutil_commands, commands_init, sizeof commands_init); |
+ memcpy(certutil_options, options_init, sizeof options_init); |
+ |
+ rv = SECU_ParseCommandLine(argc, argv, progName, &certutil); |
+ |
+ if (rv != SECSuccess) Usage(progName); |
+ |
+ if (certutil.commands[cmd_PrintSyntax].activated) { |
+ PrintSyntax(progName); |
+ } |
+ |
+ if (certutil.commands[cmd_PrintHelp].activated) { |
int i; |
- SECStatus rv; |
+ char buf[2]; |
+ const char *command = NULL; |
+ for (i = 0; i < max_cmd; i++) { |
+ if (i == cmd_PrintHelp) continue; |
+ if (certutil.commands[i].activated) { |
+ if (certutil.commands[i].flag) { |
+ buf[0] = certutil.commands[i].flag; |
+ buf[1] = 0; |
+ command = buf; |
+ } else { |
+ command = certutil.commands[i].longform; |
+ } |
+ break; |
+ } |
+ } |
+ LongUsage(progName, (command ? usage_selected : usage_all), command); |
+ exit(1); |
+ } |
- progName = PORT_Strrchr(argv[0], '/'); |
- progName = progName ? progName+1 : argv[0]; |
- memcpy(certutil_commands, commands_init, sizeof commands_init); |
- memcpy(certutil_options, options_init, sizeof options_init); |
+ if (certutil.options[opt_PasswordFile].arg) { |
+ pwdata.source = PW_FROMFILE; |
+ pwdata.data = certutil.options[opt_PasswordFile].arg; |
+ } |
+ if (certutil.options[opt_NewPasswordFile].arg) { |
+ pwdata2.source = PW_FROMFILE; |
+ pwdata2.data = certutil.options[opt_NewPasswordFile].arg; |
+ } |
- rv = SECU_ParseCommandLine(argc, argv, progName, &certutil); |
+ if (certutil.options[opt_CertDir].activated) |
+ SECU_ConfigDirectory(certutil.options[opt_CertDir].arg); |
- if (rv != SECSuccess) |
- Usage(progName); |
+ if (certutil.options[opt_SourceDir].activated) |
+ sourceDir = certutil.options[opt_SourceDir].arg; |
- if (certutil.commands[cmd_PrintSyntax].activated) { |
- PrintSyntax(progName); |
+ if (certutil.options[opt_UpgradeID].activated) |
+ upgradeID = certutil.options[opt_UpgradeID].arg; |
+ |
+ if (certutil.options[opt_UpgradeTokenName].activated) |
+ upgradeTokenName = certutil.options[opt_UpgradeTokenName].arg; |
+ |
+ if (certutil.options[opt_KeySize].activated) { |
+ keysize = PORT_Atoi(certutil.options[opt_KeySize].arg); |
+ if ((keysize < MIN_KEY_BITS) || (keysize > MAX_KEY_BITS)) { |
+ PR_fprintf(PR_STDERR, "%s -g: Keysize must be between %d and %d.\n", |
+ progName, MIN_KEY_BITS, MAX_KEY_BITS); |
+ return 255; |
+ } |
+#ifndef NSS_DISABLE_ECC |
+ if (keytype == ecKey) { |
+ PR_fprintf(PR_STDERR, "%s -g: Not for ec keys.\n", progName); |
+ return 255; |
+ } |
+#endif /* NSS_DISABLE_ECC */ |
+ } |
+ |
+ /* -h specify token name */ |
+ if (certutil.options[opt_TokenName].activated) { |
+ if (PL_strcmp(certutil.options[opt_TokenName].arg, "all") == 0) |
+ slotname = NULL; |
+ else |
+ slotname = PL_strdup(certutil.options[opt_TokenName].arg); |
+ } |
+ |
+ /* -Z hash type */ |
+ if (certutil.options[opt_Hash].activated) { |
+ char *arg = certutil.options[opt_Hash].arg; |
+ hashAlgTag = SECU_StringToSignatureAlgTag(arg); |
+ if (hashAlgTag == SEC_OID_UNKNOWN) { |
+ PR_fprintf(PR_STDERR, "%s -Z: %s is not a recognized type.\n", progName, |
+ arg); |
+ return 255; |
+ } |
+ } |
+ |
+ /* -k key type */ |
+ if (certutil.options[opt_KeyType].activated) { |
+ char *arg = certutil.options[opt_KeyType].arg; |
+ if (PL_strcmp(arg, "rsa") == 0) { |
+ keytype = rsaKey; |
+ } else if (PL_strcmp(arg, "dsa") == 0) { |
+ keytype = dsaKey; |
+#ifndef NSS_DISABLE_ECC |
+ } else if (PL_strcmp(arg, "ec") == 0) { |
+ keytype = ecKey; |
+#endif /* NSS_DISABLE_ECC */ |
+ } else if (PL_strcmp(arg, "all") == 0) { |
+ keytype = nullKey; |
+ } else { |
+ /* use an existing private/public key pair */ |
+ keysource = arg; |
+ } |
+ } else if (certutil.commands[cmd_ListKeys].activated) { |
+ keytype = nullKey; |
+ } |
+ |
+ if (certutil.options[opt_KeyOpFlagsOn].activated) { |
+ keyOpFlagsOn = GetOpFlags(certutil.options[opt_KeyOpFlagsOn].arg); |
+ } |
+ if (certutil.options[opt_KeyOpFlagsOff].activated) { |
+ keyOpFlagsOff = GetOpFlags(certutil.options[opt_KeyOpFlagsOff].arg); |
+ keyOpFlagsOn &= ~keyOpFlagsOff; /* make off override on */ |
+ } |
+ if (certutil.options[opt_KeyAttrFlags].activated) { |
+ keyAttrFlags = GetAttrFlags(certutil.options[opt_KeyAttrFlags].arg); |
+ } |
+ |
+ /* -m serial number */ |
+ if (certutil.options[opt_SerialNumber].activated) { |
+ int sn = PORT_Atoi(certutil.options[opt_SerialNumber].arg); |
+ if (sn < 0) { |
+ PR_fprintf(PR_STDERR, "%s -m: %s is not a valid serial number.\n", |
+ progName, certutil.options[opt_SerialNumber].arg); |
+ return 255; |
+ } |
+ serialNumber = sn; |
+ } |
+ |
+ /* -P certdb name prefix */ |
+ if (certutil.options[opt_DBPrefix].activated) { |
+ if (certutil.options[opt_DBPrefix].arg) { |
+ certPrefix = strdup(certutil.options[opt_DBPrefix].arg); |
+ } else { |
+ Usage(progName); |
+ } |
+ } |
+ |
+ /* --source-prefix certdb name prefix */ |
+ if (certutil.options[opt_SourcePrefix].activated) { |
+ if (certutil.options[opt_SourcePrefix].arg) { |
+ srcCertPrefix = strdup(certutil.options[opt_SourcePrefix].arg); |
+ } else { |
+ Usage(progName); |
+ } |
+ } |
+ |
+ /* -q PQG file or curve name */ |
+ if (certutil.options[opt_PQGFile].activated) { |
+#ifndef NSS_DISABLE_ECC |
+ if ((keytype != dsaKey) && (keytype != ecKey)) { |
+ PR_fprintf(PR_STDERR, |
+ "%s -q: specifies a PQG file for DSA keys" |
+ " (-k dsa) or a named curve for EC keys (-k ec)\n)", |
+ progName); |
+#else /* } */ |
+ if (keytype != dsaKey) { |
+ PR_fprintf(PR_STDERR, "%s -q: PQG file is for DSA key (-k dsa).\n)", |
+ progName); |
+#endif /* NSS_DISABLE_ECC */ |
+ return 255; |
+ } |
+ } |
+ |
+ /* -s subject name */ |
+ if (certutil.options[opt_Subject].activated) { |
+ subject = CERT_AsciiToName(certutil.options[opt_Subject].arg); |
+ if (!subject) { |
+ PR_fprintf(PR_STDERR, "%s -s: improperly formatted name: \"%s\"\n", |
+ progName, certutil.options[opt_Subject].arg); |
+ return 255; |
+ } |
+ } |
+ |
+ /* -v validity period */ |
+ if (certutil.options[opt_Validity].activated) { |
+ validityMonths = PORT_Atoi(certutil.options[opt_Validity].arg); |
+ if (validityMonths < 0) { |
+ PR_fprintf(PR_STDERR, "%s -v: incorrect validity period: \"%s\"\n", |
+ progName, certutil.options[opt_Validity].arg); |
+ return 255; |
+ } |
+ } |
+ |
+ /* -w warp months */ |
+ if (certutil.options[opt_OffsetMonths].activated) |
+ warpmonths = PORT_Atoi(certutil.options[opt_OffsetMonths].arg); |
+ |
+ /* -y public exponent (for RSA) */ |
+ if (certutil.options[opt_Exponent].activated) { |
+ publicExponent = PORT_Atoi(certutil.options[opt_Exponent].arg); |
+ if ((publicExponent != 3) && (publicExponent != 17) && |
+ (publicExponent != 65537)) { |
+ PR_fprintf(PR_STDERR, "%s -y: incorrect public exponent %d.", progName, |
+ publicExponent); |
+ PR_fprintf(PR_STDERR, "Must be 3, 17, or 65537.\n"); |
+ return 255; |
+ } |
+ } |
+ |
+ /* --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++) { |
+ if (certutil.commands[i].activated) { |
+ commandToRun = certutil.commands[i].flag; |
+ commandsEntered++; |
+ } |
+ if (commandsEntered > 1) break; |
+ } |
+ if (commandsEntered > 1) { |
+ PR_fprintf(PR_STDERR, "%s: only one command at a time!\n", progName); |
+ PR_fprintf(PR_STDERR, "You entered: "); |
+ for (i = 0; i < certutil.numCommands; i++) { |
+ if (certutil.commands[i].activated) |
+ PR_fprintf(PR_STDERR, " -%c", certutil.commands[i].flag); |
+ } |
+ PR_fprintf(PR_STDERR, "\n"); |
+ return 255; |
+ } |
+ if (commandsEntered == 0) { |
+ Usage(progName); |
+ } |
+ |
+ if (certutil.commands[cmd_ListCerts].activated || |
+ certutil.commands[cmd_PrintHelp].activated || |
+ certutil.commands[cmd_ListKeys].activated || |
+ certutil.commands[cmd_ListModules].activated || |
+ certutil.commands[cmd_CheckCertValidity].activated || |
+ certutil.commands[cmd_Version].activated) { |
+ readOnly = !certutil.options[opt_RW].activated; |
+ } |
+ |
+ /* -A, -D, -F, -M, -S, -V, and all require -n */ |
+ if ((certutil.commands[cmd_AddCert].activated || |
+ certutil.commands[cmd_DeleteCert].activated || |
+ certutil.commands[cmd_DeleteKey].activated || |
+ certutil.commands[cmd_DumpChain].activated || |
+ certutil.commands[cmd_ModifyCertTrust].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated || |
+ certutil.commands[cmd_CheckCertValidity].activated) && |
+ !certutil.options[opt_Nickname].activated) { |
+ PR_fprintf(PR_STDERR, |
+ "%s -%c: nickname is required for this command (-n).\n", |
+ progName, commandToRun); |
+ return 255; |
+ } |
+ |
+ /* -A, -E, -M, -S require trust */ |
+ if ((certutil.commands[cmd_AddCert].activated || |
+ certutil.commands[cmd_AddEmailCert].activated || |
+ certutil.commands[cmd_ModifyCertTrust].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated) && |
+ !certutil.options[opt_Trust].activated) { |
+ PR_fprintf(PR_STDERR, "%s -%c: trust is required for this command (-t).\n", |
+ progName, commandToRun); |
+ return 255; |
+ } |
+ |
+ /* if -L is given raw, ascii or dump 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, |
+ "%s: nickname is required to dump cert in raw or ascii mode.\n", |
+ progName); |
+ return 255; |
+ } |
+ |
+ /* -L can only be in (raw || ascii). */ |
+ if (certutil.commands[cmd_ListCerts].activated && |
+ certutil.options[opt_ASCIIForIO].activated && |
+ certutil.options[opt_BinaryDER].activated) { |
+ PR_fprintf(PR_STDERR, |
+ "%s: cannot specify both -r and -a when dumping cert.\n", |
+ progName); |
+ return 255; |
+ } |
+ |
+ /* If making a cert request, need a subject. */ |
+ if ((certutil.commands[cmd_CertReq].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated) && |
+ !(certutil.options[opt_Subject].activated || keysource)) { |
+ PR_fprintf(PR_STDERR, |
+ "%s -%c: subject is required to create a cert request.\n", |
+ progName, commandToRun); |
+ return 255; |
+ } |
+ |
+ /* If making a cert, need a serial number. */ |
+ if ((certutil.commands[cmd_CreateNewCert].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated) && |
+ !certutil.options[opt_SerialNumber].activated) { |
+ /* Make a default serial number from the current time. */ |
+ PRTime now = PR_Now(); |
+ LL_USHR(now, now, 19); |
+ LL_L2UI(serialNumber, now); |
+ } |
+ |
+ /* Validation needs the usage to validate for. */ |
+ if (certutil.commands[cmd_CheckCertValidity].activated && |
+ !certutil.options[opt_Usage].activated) { |
+ PR_fprintf(PR_STDERR, |
+ "%s -V: specify a usage to validate the cert for (-u).\n", |
+ progName); |
+ return 255; |
+ } |
+ |
+ /* Upgrade/Merge needs a source database and a upgrade id. */ |
+ if (certutil.commands[cmd_UpgradeMerge].activated && |
+ !(certutil.options[opt_SourceDir].activated && |
+ certutil.options[opt_UpgradeID].activated)) { |
+ |
+ PR_fprintf(PR_STDERR, |
+ "%s --upgrade-merge: specify an upgrade database directory " |
+ "(--source-dir) and\n" |
+ " an upgrade ID (--upgrade-id).\n", |
+ progName); |
+ return 255; |
+ } |
+ |
+ /* Merge needs a source database */ |
+ if (certutil.commands[cmd_Merge].activated && |
+ !certutil.options[opt_SourceDir].activated) { |
+ |
+ PR_fprintf(PR_STDERR, |
+ "%s --merge: specify an source database directory " |
+ "(--source-dir)\n", |
+ progName); |
+ return 255; |
+ } |
+ |
+ /* To make a cert, need either a issuer or to self-sign it. */ |
+ if (certutil.commands[cmd_CreateAndAddCert].activated && |
+ !(certutil.options[opt_IssuerName].activated || |
+ certutil.options[opt_SelfSign].activated)) { |
+ PR_fprintf(PR_STDERR, |
+ "%s -S: must specify issuer (-c) or self-sign (-x).\n", |
+ progName); |
+ return 255; |
+ } |
+ |
+ /* Using slotname == NULL for listing keys and certs on all slots, |
+ * but only that. */ |
+ if (!(certutil.commands[cmd_ListKeys].activated || |
+ certutil.commands[cmd_DumpChain].activated || |
+ certutil.commands[cmd_ListCerts].activated) && |
+ slotname == NULL) { |
+ PR_fprintf(PR_STDERR, "%s -%c: cannot use \"-h all\" for this command.\n", |
+ progName, commandToRun); |
+ return 255; |
+ } |
+ |
+ /* Using keytype == nullKey for list all key types, but only that. */ |
+ if (!certutil.commands[cmd_ListKeys].activated && keytype == nullKey) { |
+ PR_fprintf(PR_STDERR, "%s -%c: cannot use \"-k all\" for this command.\n", |
+ progName, commandToRun); |
+ return 255; |
+ } |
+ |
+ /* Open the input file. */ |
+ if (certutil.options[opt_InputFile].activated) { |
+ inFile = PR_Open(certutil.options[opt_InputFile].arg, PR_RDONLY, 0); |
+ if (!inFile) { |
+ PR_fprintf(PR_STDERR, |
+ "%s: unable to open \"%s\" for reading (%ld, %ld).\n", |
+ progName, certutil.options[opt_InputFile].arg, PR_GetError(), |
+ PR_GetOSError()); |
+ return 255; |
+ } |
+ } |
+ |
+ /* Open the output file. */ |
+ if (certutil.options[opt_OutputFile].activated) { |
+ outFile = PR_Open(certutil.options[opt_OutputFile].arg, |
+ PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 00660); |
+ if (!outFile) { |
+ PR_fprintf(PR_STDERR, |
+ "%s: unable to open \"%s\" for writing (%ld, %ld).\n", |
+ progName, certutil.options[opt_OutputFile].arg, PR_GetError(), |
+ PR_GetOSError()); |
+ return 255; |
+ } |
+ } |
+ |
+ name = SECU_GetOptionArg(&certutil, opt_Nickname); |
+ email = SECU_GetOptionArg(&certutil, opt_Emailaddress); |
+ |
+ PK11_SetPasswordFunc(SECU_GetModulePassword); |
+ |
+ if (PR_TRUE == initialize) { |
+ /* Initialize NSPR and NSS. */ |
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); |
+ if (!certutil.commands[cmd_UpgradeMerge].activated) { |
+ rv = NSS_Initialize(SECU_ConfigDirectory(NULL), certPrefix, certPrefix, |
+ "secmod.db", readOnly ? NSS_INIT_READONLY : 0); |
+ } else { |
+ rv = NSS_InitWithMerge(SECU_ConfigDirectory(NULL), certPrefix, certPrefix, |
+ "secmod.db", sourceDir, srcCertPrefix, |
+ srcCertPrefix, upgradeID, upgradeTokenName, |
+ readOnly ? NSS_INIT_READONLY : 0); |
+ } |
+ if (rv != SECSuccess) { |
+ SECU_PrintPRandOSError(progName); |
+ rv = SECFailure; |
+ goto shutdown; |
+ } |
+ initialized = PR_TRUE; |
+ SECU_RegisterDynamicOids(); |
+ } |
+ certHandle = CERT_GetDefaultCertDB(); |
+ |
+ if (certutil.commands[cmd_Version].activated) { |
+ printf("Certificate database content version: command not implemented.\n"); |
+ } |
+ |
+ if (PL_strcmp(slotname, "internal") == 0) |
+ slot = PK11_GetInternalKeySlot(); |
+ else if (slotname != NULL) |
+ slot = PK11_FindSlotByName(slotname); |
+ |
+ if (!slot && (certutil.commands[cmd_NewDBs].activated || |
+ certutil.commands[cmd_ModifyCertTrust].activated || |
+ certutil.commands[cmd_ChangePassword].activated || |
+ certutil.commands[cmd_TokenReset].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated || |
+ certutil.commands[cmd_AddCert].activated || |
+ certutil.commands[cmd_Merge].activated || |
+ certutil.commands[cmd_UpgradeMerge].activated || |
+ certutil.commands[cmd_AddEmailCert].activated)) { |
+ |
+ SECU_PrintError(progName, "could not find the slot %s", slotname); |
+ rv = SECFailure; |
+ goto shutdown; |
+ } |
+ |
+ /* If creating new database, initialize the password. */ |
+ if (certutil.commands[cmd_NewDBs].activated) { |
+ if (certutil.options[opt_EmptyPassword].activated && |
+ (PK11_NeedUserInit(slot))) |
+ PK11_InitPin(slot, (char *)NULL, ""); |
+ else |
+ SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, |
+ certutil.options[opt_NewPasswordFile].arg); |
+ } |
+ |
+ /* walk through the upgrade merge if necessary. |
+ * This option is more to test what some applications will want to do |
+ * to do an automatic upgrade. The --merge command is more useful for |
+ * the general case where 2 database need to be merged together. |
+ */ |
+ if (certutil.commands[cmd_UpgradeMerge].activated) { |
+ if (*upgradeTokenName == 0) { |
+ upgradeTokenName = upgradeID; |
+ } |
+ if (!PK11_IsInternal(slot)) { |
+ fprintf(stderr, "Only internal DB's can be upgraded\n"); |
+ rv = SECSuccess; |
+ goto shutdown; |
+ } |
+ if (!PK11_IsRemovable(slot)) { |
+ printf("database already upgraded.\n"); |
+ rv = SECSuccess; |
+ goto shutdown; |
+ } |
+ if (!PK11_NeedLogin(slot)) { |
+ printf("upgrade complete!\n"); |
+ rv = SECSuccess; |
+ goto shutdown; |
+ } |
+ /* authenticate to the old DB if necessary */ |
+ if (PORT_Strcmp(PK11_GetTokenName(slot), upgradeTokenName) == 0) { |
+ /* if we need a password, supply it. This will be the password |
+ * for the old database */ |
+ rv = PK11_Authenticate(slot, PR_FALSE, &pwdata2); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "Could not get password for %s", |
+ upgradeTokenName); |
+ goto shutdown; |
+ } |
+ /* |
+ * if we succeeded above, but still aren't logged in, that means |
+ * we just supplied the password for the old database. We may |
+ * need the password for the new database. NSS will automatically |
+ * change the token names at this point |
+ */ |
+ if (PK11_IsLoggedIn(slot, &pwdata)) { |
+ printf("upgrade complete!\n"); |
+ rv = SECSuccess; |
+ goto shutdown; |
+ } |
} |
- if (certutil.commands[cmd_PrintHelp].activated) { |
- int i; |
- char buf[2]; |
- const char *command = NULL; |
- for (i = 0; i < max_cmd; i++) { |
- if (i == cmd_PrintHelp) |
- continue; |
- if (certutil.commands[i].activated) { |
- if (certutil.commands[i].flag) { |
- buf[0] = certutil.commands[i].flag; |
- buf[1] = 0; |
- command = buf; |
- } |
- else { |
- command = certutil.commands[i].longform; |
- } |
- break; |
- } |
- } |
- LongUsage(progName, (command ? usage_selected : usage_all), command); |
- exit(1); |
+ /* call PK11_IsPresent to update our cached token information */ |
+ if (!PK11_IsPresent(slot)) { |
+ /* this shouldn't happen. We call isPresent to force a token |
+ * info update */ |
+ fprintf(stderr, "upgrade/merge internal error\n"); |
+ rv = SECFailure; |
+ goto shutdown; |
} |
- if (certutil.options[opt_PasswordFile].arg) { |
- pwdata.source = PW_FROMFILE; |
- pwdata.data = certutil.options[opt_PasswordFile].arg; |
+ /* the token is now set to the state of the source database, |
+ * if we need a password for it, PK11_Authenticate will |
+ * automatically prompt us */ |
+ rv = PK11_Authenticate(slot, PR_FALSE, &pwdata); |
+ if (rv == SECSuccess) { |
+ printf("upgrade complete!\n"); |
+ } else { |
+ SECU_PrintError(progName, "Could not get password for %s", |
+ PK11_GetTokenName(slot)); |
} |
- if (certutil.options[opt_NewPasswordFile].arg) { |
- pwdata2.source = PW_FROMFILE; |
- pwdata2.data = certutil.options[opt_NewPasswordFile].arg; |
+ goto shutdown; |
+ } |
+ |
+ /* |
+ * merge 2 databases. |
+ */ |
+ if (certutil.commands[cmd_Merge].activated) { |
+ PK11SlotInfo *sourceSlot = NULL; |
+ PK11MergeLog *log; |
+ char *modspec = |
+ PR_smprintf("configDir='%s' certPrefix='%s' tokenDescription='%s'", |
+ sourceDir, srcCertPrefix, |
+ *upgradeTokenName ? upgradeTokenName : "Source Database"); |
+ |
+ if (!modspec) { |
+ rv = SECFailure; |
+ goto shutdown; |
} |
- if (certutil.options[opt_CertDir].activated) |
- SECU_ConfigDirectory(certutil.options[opt_CertDir].arg); |
- |
- if (certutil.options[opt_SourceDir].activated) |
- sourceDir = certutil.options[opt_SourceDir].arg; |
- |
- if (certutil.options[opt_UpgradeID].activated) |
- upgradeID = certutil.options[opt_UpgradeID].arg; |
- |
- if (certutil.options[opt_UpgradeTokenName].activated) |
- upgradeTokenName = certutil.options[opt_UpgradeTokenName].arg; |
- |
- if (certutil.options[opt_KeySize].activated) { |
- keysize = PORT_Atoi(certutil.options[opt_KeySize].arg); |
- if ((keysize < MIN_KEY_BITS) || (keysize > MAX_KEY_BITS)) { |
- PR_fprintf(PR_STDERR, |
- "%s -g: Keysize must be between %d and %d.\n", |
- progName, MIN_KEY_BITS, MAX_KEY_BITS); |
- return 255; |
- } |
-#ifndef NSS_DISABLE_ECC |
- if (keytype == ecKey) { |
- PR_fprintf(PR_STDERR, "%s -g: Not for ec keys.\n", progName); |
- return 255; |
- } |
-#endif /* NSS_DISABLE_ECC */ |
- |
+ sourceSlot = SECMOD_OpenUserDB(modspec); |
+ PR_smprintf_free(modspec); |
+ if (!sourceSlot) { |
+ SECU_PrintError(progName, "couldn't open source database"); |
+ rv = SECFailure; |
+ goto shutdown; |
} |
- /* -h specify token name */ |
- if (certutil.options[opt_TokenName].activated) { |
- if (PL_strcmp(certutil.options[opt_TokenName].arg, "all") == 0) |
- slotname = NULL; |
- else |
- slotname = PL_strdup(certutil.options[opt_TokenName].arg); |
+ rv = PK11_Authenticate(slot, PR_FALSE, &pwdata); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "Couldn't get password for %s", |
+ PK11_GetTokenName(slot)); |
+ goto merge_fail; |
} |
- /* -Z hash type */ |
- if (certutil.options[opt_Hash].activated) { |
- char * arg = certutil.options[opt_Hash].arg; |
- hashAlgTag = SECU_StringToSignatureAlgTag(arg); |
- if (hashAlgTag == SEC_OID_UNKNOWN) { |
- PR_fprintf(PR_STDERR, "%s -Z: %s is not a recognized type.\n", |
- progName, arg); |
- return 255; |
- } |
+ rv = PK11_Authenticate(sourceSlot, PR_FALSE, &pwdata2); |
+ if (rv != SECSuccess) { |
+ SECU_PrintError(progName, "Couldn't get password for %s", |
+ PK11_GetTokenName(sourceSlot)); |
+ goto merge_fail; |
} |
- /* -k key type */ |
- if (certutil.options[opt_KeyType].activated) { |
- char * arg = certutil.options[opt_KeyType].arg; |
- if (PL_strcmp(arg, "rsa") == 0) { |
- keytype = rsaKey; |
- } else if (PL_strcmp(arg, "dsa") == 0) { |
- keytype = dsaKey; |
-#ifndef NSS_DISABLE_ECC |
- } else if (PL_strcmp(arg, "ec") == 0) { |
- keytype = ecKey; |
-#endif /* NSS_DISABLE_ECC */ |
- } else if (PL_strcmp(arg, "all") == 0) { |
- keytype = nullKey; |
- } else { |
- /* use an existing private/public key pair */ |
- keysource = arg; |
- } |
- } else if (certutil.commands[cmd_ListKeys].activated) { |
- keytype = nullKey; |
+ log = PK11_CreateMergeLog(); |
+ if (!log) { |
+ rv = SECFailure; |
+ SECU_PrintError(progName, "couldn't create error log"); |
+ goto merge_fail; |
} |
- if (certutil.options[opt_KeyOpFlagsOn].activated) { |
- keyOpFlagsOn = GetOpFlags(certutil.options[opt_KeyOpFlagsOn].arg); |
+ rv = PK11_MergeTokens(slot, sourceSlot, log, &pwdata, &pwdata2); |
+ if (rv != SECSuccess) { |
+ DumpMergeLog(progName, log); |
} |
- if (certutil.options[opt_KeyOpFlagsOff].activated) { |
- keyOpFlagsOff = GetOpFlags(certutil.options[opt_KeyOpFlagsOff].arg); |
- keyOpFlagsOn &=~keyOpFlagsOff; /* make off override on */ |
+ PK11_DestroyMergeLog(log); |
+ |
+ merge_fail: |
+ SECMOD_CloseUserDB(sourceSlot); |
+ PK11_FreeSlot(sourceSlot); |
+ goto shutdown; |
+ } |
+ |
+ /* The following 8 options are mutually exclusive with all others. */ |
+ |
+ /* 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); |
} |
- if (certutil.options[opt_KeyAttrFlags].activated) { |
- keyAttrFlags = GetAttrFlags(certutil.options[opt_KeyAttrFlags].arg); |
+ goto shutdown; |
+ } |
+ if (certutil.commands[cmd_DumpChain].activated) { |
+ rv = |
+ DumpChain(certHandle, name, certutil.options[opt_ASCIIForIO].activated); |
+ goto shutdown; |
+ } |
+ /* XXX needs work */ |
+ /* List keys (-K) */ |
+ if (certutil.commands[cmd_ListKeys].activated) { |
+ rv = ListKeys(slot, name, 0 /*keyindex*/, keytype, PR_FALSE /*dopriv*/, |
+ &pwdata); |
+ goto shutdown; |
+ } |
+ /* List modules (-U) */ |
+ if (certutil.commands[cmd_ListModules].activated) { |
+ rv = ListModules(); |
+ goto shutdown; |
+ } |
+ /* Delete cert (-D) */ |
+ if (certutil.commands[cmd_DeleteCert].activated) { |
+ rv = DeleteCert(certHandle, name); |
+ goto shutdown; |
+ } |
+ /* Delete key (-F) */ |
+ if (certutil.commands[cmd_DeleteKey].activated) { |
+ rv = DeleteKey(name, &pwdata); |
+ goto shutdown; |
+ } |
+ /* Modify trust attribute for cert (-M) */ |
+ if (certutil.commands[cmd_ModifyCertTrust].activated) { |
+ rv = ChangeTrustAttributes(certHandle, slot, name, |
+ certutil.options[opt_Trust].arg, &pwdata); |
+ goto shutdown; |
+ } |
+ /* Change key db password (-W) (future - change pw to slot?) */ |
+ if (certutil.commands[cmd_ChangePassword].activated) { |
+ rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, |
+ certutil.options[opt_NewPasswordFile].arg); |
+ goto shutdown; |
+ } |
+ /* Reset the a token */ |
+ if (certutil.commands[cmd_TokenReset].activated) { |
+ char *sso_pass = ""; |
+ |
+ if (certutil.options[opt_SSOPass].activated) { |
+ sso_pass = certutil.options[opt_SSOPass].arg; |
+ } |
+ rv = PK11_ResetToken(slot, sso_pass); |
+ |
+ goto shutdown; |
+ } |
+ /* Check cert validity against current time (-V) */ |
+ if (certutil.commands[cmd_CheckCertValidity].activated) { |
+ /* XXX temporary hack for fips - must log in to get priv key */ |
+ if (certutil.options[opt_VerifySig].activated) { |
+ if (slot && PK11_NeedLogin(slot)) { |
+ SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, &pwdata); |
+ if (newrv != SECSuccess) { |
+ SECU_PrintError(progName, "could not authenticate to token %s.", |
+ PK11_GetTokenName(slot)); |
+ goto shutdown; |
+ } |
+ } |
+ } |
+ rv = ValidateCert(certHandle, name, certutil.options[opt_ValidityTime].arg, |
+ certutil.options[opt_Usage].arg, |
+ certutil.options[opt_VerifySig].activated, |
+ certutil.options[opt_DetailedInfo].activated, |
+ certutil.options[opt_ASCIIForIO].activated, &pwdata); |
+ if (rv != SECSuccess && PR_GetError() == SEC_ERROR_INVALID_ARGS) |
+ SECU_PrintError(progName, "validation failed"); |
+ goto shutdown; |
+ } |
+ |
+ /* |
+ * Key generation |
+ */ |
+ |
+ /* These commands may require keygen. */ |
+ if (certutil.commands[cmd_CertReq].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated || |
+ certutil.commands[cmd_GenKeyPair].activated) { |
+ if (keysource) { |
+ CERTCertificate *keycert; |
+ keycert = CERT_FindCertByNicknameOrEmailAddr(certHandle, keysource); |
+ if (!keycert) { |
+ keycert = PK11_FindCertFromNickname(keysource, NULL); |
+ if (!keycert) { |
+ SECU_PrintError(progName, "%s is neither a key-type nor a nickname", |
+ keysource); |
+ return SECFailure; |
+ } |
+ } |
+ privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata); |
+ if (privkey) pubkey = CERT_ExtractPublicKey(keycert); |
+ if (!pubkey) { |
+ SECU_PrintError(progName, "Could not get keys from cert %s", keysource); |
+ rv = SECFailure; |
+ CERT_DestroyCertificate(keycert); |
+ goto shutdown; |
+ } |
+ keytype = privkey->keyType; |
+ /* On CertReq for renewal if no subject has been |
+ * specified obtain it from the certificate. |
+ */ |
+ if (certutil.commands[cmd_CertReq].activated && !subject) { |
+ subject = CERT_AsciiToName(keycert->subjectName); |
+ if (!subject) { |
+ SECU_PrintError(progName, "Could not get subject from certificate %s", |
+ keysource); |
+ CERT_DestroyCertificate(keycert); |
+ rv = SECFailure; |
+ goto shutdown; |
+ } |
+ } |
+ CERT_DestroyCertificate(keycert); |
+ } else { |
+ privkey = CERTUTIL_GeneratePrivateKey( |
+ keytype, slot, keysize, publicExponent, |
+ certutil.options[opt_NoiseFile].arg, &pubkey, |
+ certutil.options[opt_PQGFile].arg, keyAttrFlags, keyOpFlagsOn, |
+ keyOpFlagsOff, &pwdata); |
+ if (privkey == NULL) { |
+ SECU_PrintError(progName, "unable to generate key(s)\n"); |
+ rv = SECFailure; |
+ goto shutdown; |
+ } |
+ } |
+ privkey->wincx = &pwdata; |
+ PORT_Assert(pubkey != NULL); |
+ |
+ /* If all that was needed was keygen, exit. */ |
+ if (certutil.commands[cmd_GenKeyPair].activated) { |
+ rv = SECSuccess; |
+ goto shutdown; |
+ } |
+ } |
+ |
+ /* If we need a list of extensions convert the flags into list format */ |
+ if (certutil.commands[cmd_CertReq].activated || |
+ certutil.commands[cmd_CreateAndAddCert].activated || |
+ certutil.commands[cmd_CreateNewCert].activated) { |
+ certutil_extns[ext_keyUsage].activated = |
+ certutil.options[opt_AddCmdKeyUsageExt].activated; |
+ if (!certutil_extns[ext_keyUsage].activated) { |
+ certutil_extns[ext_keyUsage].activated = |
+ certutil.options[opt_AddKeyUsageExt].activated; |
+ } else { |
+ certutil_extns[ext_keyUsage].arg = |
+ certutil.options[opt_AddCmdKeyUsageExt].arg; |
+ } |
+ certutil_extns[ext_basicConstraint].activated = |
+ certutil.options[opt_AddBasicConstraintExt].activated; |
+ certutil_extns[ext_nameConstraints].activated = |
+ certutil.options[opt_AddNameConstraintsExt].activated; |
+ certutil_extns[ext_authorityKeyID].activated = |
+ certutil.options[opt_AddAuthorityKeyIDExt].activated; |
+ certutil_extns[ext_subjectKeyID].activated = |
+ certutil.options[opt_AddSubjectKeyIDExt].activated; |
+ certutil_extns[ext_CRLDistPts].activated = |
+ certutil.options[opt_AddCRLDistPtsExt].activated; |
+ certutil_extns[ext_NSCertType].activated = |
+ certutil.options[opt_AddCmdNSCertTypeExt].activated; |
+ if (!certutil_extns[ext_NSCertType].activated) { |
+ certutil_extns[ext_NSCertType].activated = |
+ certutil.options[opt_AddNSCertTypeExt].activated; |
+ } else { |
+ certutil_extns[ext_NSCertType].arg = |
+ certutil.options[opt_AddCmdNSCertTypeExt].arg; |
} |
- /* -m serial number */ |
- if (certutil.options[opt_SerialNumber].activated) { |
- int sn = PORT_Atoi(certutil.options[opt_SerialNumber].arg); |
- if (sn < 0) { |
- PR_fprintf(PR_STDERR, "%s -m: %s is not a valid serial number.\n", |
- progName, certutil.options[opt_SerialNumber].arg); |
- return 255; |
- } |
- serialNumber = sn; |
+ certutil_extns[ext_extKeyUsage].activated = |
+ certutil.options[opt_AddCmdExtKeyUsageExt].activated; |
+ if (!certutil_extns[ext_extKeyUsage].activated) { |
+ certutil_extns[ext_extKeyUsage].activated = |
+ certutil.options[opt_AddExtKeyUsageExt].activated; |
+ } else { |
+ 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; |
} |
- /* -P certdb name prefix */ |
- if (certutil.options[opt_DBPrefix].activated) { |
- if (certutil.options[opt_DBPrefix].arg) { |
- certPrefix = strdup(certutil.options[opt_DBPrefix].arg); |
- } else { |
- Usage(progName); |
- } |
+ certutil_extns[ext_authInfoAcc].activated = |
+ certutil.options[opt_AddAuthInfoAccExt].activated; |
+ certutil_extns[ext_subjInfoAcc].activated = |
+ certutil.options[opt_AddSubjInfoAccExt].activated; |
+ certutil_extns[ext_certPolicies].activated = |
+ certutil.options[opt_AddCertPoliciesExt].activated; |
+ certutil_extns[ext_policyMappings].activated = |
+ certutil.options[opt_AddPolicyMapExt].activated; |
+ certutil_extns[ext_policyConstr].activated = |
+ certutil.options[opt_AddPolicyConstrExt].activated; |
+ certutil_extns[ext_inhibitAnyPolicy].activated = |
+ certutil.options[opt_AddInhibAnyExt].activated; |
+ } |
+ |
+ /* -A -C or -E Read inFile */ |
+ if (certutil.commands[cmd_CreateNewCert].activated || |
+ certutil.commands[cmd_AddCert].activated || |
+ certutil.commands[cmd_AddEmailCert].activated) { |
+ PRBool isCreate = certutil.commands[cmd_CreateNewCert].activated; |
+ rv = SECU_ReadDERFromFile(isCreate ? &certReqDER : &certDER, inFile, |
+ certutil.options[opt_ASCIIForIO].activated, |
+ PR_TRUE); |
+ if (rv) goto shutdown; |
+ } |
+ |
+ /* |
+ * Certificate request |
+ */ |
+ |
+ /* Make a cert request (-R). */ |
+ if (certutil.commands[cmd_CertReq].activated) { |
+ rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject, |
+ certutil.options[opt_PhoneNumber].arg, |
+ certutil.options[opt_ASCIIForIO].activated, |
+ 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; |
+ privkey->wincx = &pwdata; |
+ } |
+ |
+ /* |
+ * Certificate creation |
+ */ |
+ |
+ /* If making and adding a cert, create a cert request file first without |
+ * any extensions, then load it with the command line extensions |
+ * and output the cert to another file. |
+ */ |
+ if (certutil.commands[cmd_CreateAndAddCert].activated) { |
+ static certutilExtnList nullextnlist = {{PR_FALSE, NULL}}; |
+ rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject, |
+ certutil.options[opt_PhoneNumber].arg, |
+ PR_FALSE, /* do not BASE64-encode regardless of -a option */ |
+ NULL, NULL, nullextnlist, |
+ (certutil.options[opt_GenericExtensions].activated |
+ ? certutil.options[opt_GenericExtensions].arg |
+ : NULL), |
+ &certReqDER); |
+ if (rv) goto shutdown; |
+ privkey->wincx = &pwdata; |
+ } |
+ |
+ /* Create a certificate (-C or -S). */ |
+ if (certutil.commands[cmd_CreateAndAddCert].activated || |
+ certutil.commands[cmd_CreateNewCert].activated) { |
+ rv = CreateCert(certHandle, slot, certutil.options[opt_IssuerName].arg, |
+ &certReqDER, &privkey, &pwdata, hashAlgTag, serialNumber, |
+ warpmonths, validityMonths, |
+ certutil.options[opt_ExtendedEmailAddrs].arg, |
+ certutil.options[opt_ExtendedDNSNames].arg, |
+ certutil.options[opt_ASCIIForIO].activated && |
+ 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) goto shutdown; |
+ } |
+ |
+ /* |
+ * Adding a cert to the database (or slot) |
+ */ |
+ |
+ /* -A -E or -S Add the cert to the DB */ |
+ if (certutil.commands[cmd_CreateAndAddCert].activated || |
+ certutil.commands[cmd_AddCert].activated || |
+ certutil.commands[cmd_AddEmailCert].activated) { |
+ if (strstr(certutil.options[opt_Trust].arg, "u")) { |
+ fprintf(stderr, |
+ "Notice: Trust flag u is set automatically if the " |
+ "private key is present.\n"); |
} |
+ rv = AddCert(slot, certHandle, name, certutil.options[opt_Trust].arg, |
+ &certDER, certutil.commands[cmd_AddEmailCert].activated, |
+ &pwdata); |
+ if (rv) goto shutdown; |
+ } |
- /* --source-prefix certdb name prefix */ |
- if (certutil.options[opt_SourcePrefix].activated) { |
- if (certutil.options[opt_SourcePrefix].arg) { |
- srcCertPrefix = strdup(certutil.options[opt_SourcePrefix].arg); |
- } else { |
- Usage(progName); |
- } |
+ if (certutil.commands[cmd_CertReq].activated || |
+ certutil.commands[cmd_CreateNewCert].activated) { |
+ SECItem *item = |
+ certutil.commands[cmd_CertReq].activated ? &certReqDER : &certDER; |
+ PRInt32 written = PR_Write(outFile, item->data, item->len); |
+ if (written < 0 || (PRUint32)written != item->len) { |
+ rv = SECFailure; |
} |
- |
- /* -q PQG file or curve name */ |
- if (certutil.options[opt_PQGFile].activated) { |
-#ifndef NSS_DISABLE_ECC |
- if ((keytype != dsaKey) && (keytype != ecKey)) { |
- PR_fprintf(PR_STDERR, "%s -q: specifies a PQG file for DSA keys" \ |
- " (-k dsa) or a named curve for EC keys (-k ec)\n)", |
- progName); |
-#else /* } */ |
- if (keytype != dsaKey) { |
- PR_fprintf(PR_STDERR, "%s -q: PQG file is for DSA key (-k dsa).\n)", |
- progName); |
-#endif /* NSS_DISABLE_ECC */ |
- return 255; |
- } |
- } |
- |
- /* -s subject name */ |
- if (certutil.options[opt_Subject].activated) { |
- subject = CERT_AsciiToName(certutil.options[opt_Subject].arg); |
- if (!subject) { |
- PR_fprintf(PR_STDERR, "%s -s: improperly formatted name: \"%s\"\n", |
- progName, certutil.options[opt_Subject].arg); |
- return 255; |
- } |
- } |
- |
- /* -v validity period */ |
- if (certutil.options[opt_Validity].activated) { |
- validityMonths = PORT_Atoi(certutil.options[opt_Validity].arg); |
- if (validityMonths < 0) { |
- PR_fprintf(PR_STDERR, "%s -v: incorrect validity period: \"%s\"\n", |
- progName, certutil.options[opt_Validity].arg); |
- return 255; |
- } |
- } |
- |
- /* -w warp months */ |
- if (certutil.options[opt_OffsetMonths].activated) |
- warpmonths = PORT_Atoi(certutil.options[opt_OffsetMonths].arg); |
- |
- /* -y public exponent (for RSA) */ |
- if (certutil.options[opt_Exponent].activated) { |
- publicExponent = PORT_Atoi(certutil.options[opt_Exponent].arg); |
- if ((publicExponent != 3) && |
- (publicExponent != 17) && |
- (publicExponent != 65537)) { |
- PR_fprintf(PR_STDERR, "%s -y: incorrect public exponent %d.", |
- progName, publicExponent); |
- PR_fprintf(PR_STDERR, "Must be 3, 17, or 65537.\n"); |
- return 255; |
- } |
- } |
- |
- /* --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++) { |
- if (certutil.commands[i].activated) { |
- commandToRun = certutil.commands[i].flag; |
- commandsEntered++; |
- } |
- if (commandsEntered > 1) |
- break; |
- } |
- if (commandsEntered > 1) { |
- PR_fprintf(PR_STDERR, "%s: only one command at a time!\n", progName); |
- PR_fprintf(PR_STDERR, "You entered: "); |
- for (i=0; i< certutil.numCommands; i++) { |
- if (certutil.commands[i].activated) |
- PR_fprintf(PR_STDERR, " -%c", certutil.commands[i].flag); |
- } |
- PR_fprintf(PR_STDERR, "\n"); |
- return 255; |
- } |
- if (commandsEntered == 0) { |
- Usage(progName); |
- } |
- |
- if (certutil.commands[cmd_ListCerts].activated || |
- certutil.commands[cmd_PrintHelp].activated || |
- certutil.commands[cmd_ListKeys].activated || |
- certutil.commands[cmd_ListModules].activated || |
- certutil.commands[cmd_CheckCertValidity].activated || |
- certutil.commands[cmd_Version].activated ) { |
- readOnly = !certutil.options[opt_RW].activated; |
- } |
- |
- /* -A, -D, -F, -M, -S, -V, and all require -n */ |
- if ((certutil.commands[cmd_AddCert].activated || |
- certutil.commands[cmd_DeleteCert].activated || |
- certutil.commands[cmd_DeleteKey].activated || |
- certutil.commands[cmd_DumpChain].activated || |
- certutil.commands[cmd_ModifyCertTrust].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated || |
- certutil.commands[cmd_CheckCertValidity].activated) && |
- !certutil.options[opt_Nickname].activated) { |
- PR_fprintf(PR_STDERR, |
- "%s -%c: nickname is required for this command (-n).\n", |
- progName, commandToRun); |
- return 255; |
- } |
- |
- /* -A, -E, -M, -S require trust */ |
- if ((certutil.commands[cmd_AddCert].activated || |
- certutil.commands[cmd_AddEmailCert].activated || |
- certutil.commands[cmd_ModifyCertTrust].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated) && |
- !certutil.options[opt_Trust].activated) { |
- PR_fprintf(PR_STDERR, |
- "%s -%c: trust is required for this command (-t).\n", |
- progName, commandToRun); |
- return 255; |
- } |
- |
- /* if -L is given raw, ascii or dump 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, |
- "%s: nickname is required to dump cert in raw or ascii mode.\n", |
- progName); |
- return 255; |
- } |
- |
- /* -L can only be in (raw || ascii). */ |
- if (certutil.commands[cmd_ListCerts].activated && |
- certutil.options[opt_ASCIIForIO].activated && |
- certutil.options[opt_BinaryDER].activated) { |
- PR_fprintf(PR_STDERR, |
- "%s: cannot specify both -r and -a when dumping cert.\n", |
- progName); |
- return 255; |
- } |
- |
- /* If making a cert request, need a subject. */ |
- if ((certutil.commands[cmd_CertReq].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated) && |
- !(certutil.options[opt_Subject].activated || keysource)) { |
- PR_fprintf(PR_STDERR, |
- "%s -%c: subject is required to create a cert request.\n", |
- progName, commandToRun); |
- return 255; |
- } |
- |
- /* If making a cert, need a serial number. */ |
- if ((certutil.commands[cmd_CreateNewCert].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated) && |
- !certutil.options[opt_SerialNumber].activated) { |
- /* Make a default serial number from the current time. */ |
- PRTime now = PR_Now(); |
- LL_USHR(now, now, 19); |
- LL_L2UI(serialNumber, now); |
- } |
- |
- /* Validation needs the usage to validate for. */ |
- if (certutil.commands[cmd_CheckCertValidity].activated && |
- !certutil.options[opt_Usage].activated) { |
- PR_fprintf(PR_STDERR, |
- "%s -V: specify a usage to validate the cert for (-u).\n", |
- progName); |
- return 255; |
- } |
- |
- /* Upgrade/Merge needs a source database and a upgrade id. */ |
- if (certutil.commands[cmd_UpgradeMerge].activated && |
- !(certutil.options[opt_SourceDir].activated && |
- certutil.options[opt_UpgradeID].activated)) { |
- |
- PR_fprintf(PR_STDERR, |
- "%s --upgrade-merge: specify an upgrade database directory " |
- "(--source-dir) and\n" |
- " an upgrade ID (--upgrade-id).\n", |
- progName); |
- return 255; |
- } |
- |
- /* Merge needs a source database */ |
- if (certutil.commands[cmd_Merge].activated && |
- !certutil.options[opt_SourceDir].activated) { |
- |
- |
- PR_fprintf(PR_STDERR, |
- "%s --merge: specify an source database directory " |
- "(--source-dir)\n", |
- progName); |
- return 255; |
- } |
- |
- |
- /* To make a cert, need either a issuer or to self-sign it. */ |
- if (certutil.commands[cmd_CreateAndAddCert].activated && |
- !(certutil.options[opt_IssuerName].activated || |
- certutil.options[opt_SelfSign].activated)) { |
- PR_fprintf(PR_STDERR, |
- "%s -S: must specify issuer (-c) or self-sign (-x).\n", |
- progName); |
- return 255; |
- } |
- |
- /* Using slotname == NULL for listing keys and certs on all slots, |
- * but only that. */ |
- if (!(certutil.commands[cmd_ListKeys].activated || |
- certutil.commands[cmd_DumpChain].activated || |
- certutil.commands[cmd_ListCerts].activated) && slotname == NULL) { |
- PR_fprintf(PR_STDERR, |
- "%s -%c: cannot use \"-h all\" for this command.\n", |
- progName, commandToRun); |
- return 255; |
- } |
- |
- /* Using keytype == nullKey for list all key types, but only that. */ |
- if (!certutil.commands[cmd_ListKeys].activated && keytype == nullKey) { |
- PR_fprintf(PR_STDERR, |
- "%s -%c: cannot use \"-k all\" for this command.\n", |
- progName, commandToRun); |
- return 255; |
- } |
- |
- /* Open the input file. */ |
- if (certutil.options[opt_InputFile].activated) { |
- inFile = PR_Open(certutil.options[opt_InputFile].arg, PR_RDONLY, 0); |
- if (!inFile) { |
- PR_fprintf(PR_STDERR, |
- "%s: unable to open \"%s\" for reading (%ld, %ld).\n", |
- progName, certutil.options[opt_InputFile].arg, |
- PR_GetError(), PR_GetOSError()); |
- return 255; |
- } |
- } |
- |
- /* Open the output file. */ |
- if (certutil.options[opt_OutputFile].activated) { |
- outFile = PR_Open(certutil.options[opt_OutputFile].arg, |
- PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 00660); |
- if (!outFile) { |
- PR_fprintf(PR_STDERR, |
- "%s: unable to open \"%s\" for writing (%ld, %ld).\n", |
- progName, certutil.options[opt_OutputFile].arg, |
- PR_GetError(), PR_GetOSError()); |
- return 255; |
- } |
- } |
- |
- name = SECU_GetOptionArg(&certutil, opt_Nickname); |
- email = SECU_GetOptionArg(&certutil, opt_Emailaddress); |
- |
- PK11_SetPasswordFunc(SECU_GetModulePassword); |
- |
- if (PR_TRUE == initialize) { |
- /* Initialize NSPR and NSS. */ |
- PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); |
- if (!certutil.commands[cmd_UpgradeMerge].activated) { |
- rv = NSS_Initialize(SECU_ConfigDirectory(NULL), |
- certPrefix, certPrefix, |
- "secmod.db", readOnly ? NSS_INIT_READONLY: 0); |
- } else { |
- rv = NSS_InitWithMerge(SECU_ConfigDirectory(NULL), |
- certPrefix, certPrefix, "secmod.db", |
- sourceDir, srcCertPrefix, srcCertPrefix, |
- upgradeID, upgradeTokenName, |
- readOnly ? NSS_INIT_READONLY: 0); |
- } |
- if (rv != SECSuccess) { |
- SECU_PrintPRandOSError(progName); |
- rv = SECFailure; |
- goto shutdown; |
- } |
- initialized = PR_TRUE; |
- SECU_RegisterDynamicOids(); |
- } |
- certHandle = CERT_GetDefaultCertDB(); |
- |
- if (certutil.commands[cmd_Version].activated) { |
- printf("Certificate database content version: command not implemented.\n"); |
- } |
- |
- if (PL_strcmp(slotname, "internal") == 0) |
- slot = PK11_GetInternalKeySlot(); |
- else if (slotname != NULL) |
- slot = PK11_FindSlotByName(slotname); |
- |
- if ( !slot && (certutil.commands[cmd_NewDBs].activated || |
- certutil.commands[cmd_ModifyCertTrust].activated || |
- certutil.commands[cmd_ChangePassword].activated || |
- certutil.commands[cmd_TokenReset].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated || |
- certutil.commands[cmd_AddCert].activated || |
- certutil.commands[cmd_Merge].activated || |
- certutil.commands[cmd_UpgradeMerge].activated || |
- certutil.commands[cmd_AddEmailCert].activated)) { |
- |
- SECU_PrintError(progName, "could not find the slot %s",slotname); |
- rv = SECFailure; |
- goto shutdown; |
- } |
- |
- /* If creating new database, initialize the password. */ |
- if (certutil.commands[cmd_NewDBs].activated) { |
- if(certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot))) |
- PK11_InitPin(slot, (char*)NULL, ""); |
- else |
- SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, |
- certutil.options[opt_NewPasswordFile].arg); |
- } |
- |
- /* walk through the upgrade merge if necessary. |
- * This option is more to test what some applications will want to do |
- * to do an automatic upgrade. The --merge command is more useful for |
- * the general case where 2 database need to be merged together. |
- */ |
- if (certutil.commands[cmd_UpgradeMerge].activated) { |
- if (*upgradeTokenName == 0) { |
- upgradeTokenName = upgradeID; |
- } |
- if (!PK11_IsInternal(slot)) { |
- fprintf(stderr, "Only internal DB's can be upgraded\n"); |
- rv = SECSuccess; |
- goto shutdown; |
- } |
- if (!PK11_IsRemovable(slot)) { |
- printf("database already upgraded.\n"); |
- rv = SECSuccess; |
- goto shutdown; |
- } |
- if (!PK11_NeedLogin(slot)) { |
- printf("upgrade complete!\n"); |
- rv = SECSuccess; |
- goto shutdown; |
- } |
- /* authenticate to the old DB if necessary */ |
- if (PORT_Strcmp(PK11_GetTokenName(slot), upgradeTokenName) == 0) { |
- /* if we need a password, supply it. This will be the password |
- * for the old database */ |
- rv = PK11_Authenticate(slot, PR_FALSE, &pwdata2); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "Could not get password for %s", |
- upgradeTokenName); |
- goto shutdown; |
- } |
- /* |
- * if we succeeded above, but still aren't logged in, that means |
- * we just supplied the password for the old database. We may |
- * need the password for the new database. NSS will automatically |
- * change the token names at this point |
- */ |
- if (PK11_IsLoggedIn(slot, &pwdata)) { |
- printf("upgrade complete!\n"); |
- rv = SECSuccess; |
- goto shutdown; |
- } |
- } |
- |
- /* call PK11_IsPresent to update our cached token information */ |
- if (!PK11_IsPresent(slot)) { |
- /* this shouldn't happen. We call isPresent to force a token |
- * info update */ |
- fprintf(stderr, "upgrade/merge internal error\n"); |
- rv = SECFailure; |
- goto shutdown; |
- } |
- |
- /* the token is now set to the state of the source database, |
- * if we need a password for it, PK11_Authenticate will |
- * automatically prompt us */ |
- rv = PK11_Authenticate(slot, PR_FALSE, &pwdata); |
- if (rv == SECSuccess) { |
- printf("upgrade complete!\n"); |
- } else { |
- SECU_PrintError(progName, "Could not get password for %s", |
- PK11_GetTokenName(slot)); |
- } |
- goto shutdown; |
- } |
- |
- /* |
- * merge 2 databases. |
- */ |
- if (certutil.commands[cmd_Merge].activated) { |
- PK11SlotInfo *sourceSlot = NULL; |
- PK11MergeLog *log; |
- char *modspec = PR_smprintf( |
- "configDir='%s' certPrefix='%s' tokenDescription='%s'", |
- sourceDir, srcCertPrefix, |
- *upgradeTokenName ? upgradeTokenName : "Source Database"); |
- |
- if (!modspec) { |
- rv = SECFailure; |
- goto shutdown; |
- } |
- |
- sourceSlot = SECMOD_OpenUserDB(modspec); |
- PR_smprintf_free(modspec); |
- if (!sourceSlot) { |
- SECU_PrintError(progName, "couldn't open source database"); |
- rv = SECFailure; |
- goto shutdown; |
- } |
- |
- rv = PK11_Authenticate(slot, PR_FALSE, &pwdata); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "Couldn't get password for %s", |
- PK11_GetTokenName(slot)); |
- goto merge_fail; |
- } |
- |
- rv = PK11_Authenticate(sourceSlot, PR_FALSE, &pwdata2); |
- if (rv != SECSuccess) { |
- SECU_PrintError(progName, "Couldn't get password for %s", |
- PK11_GetTokenName(sourceSlot)); |
- goto merge_fail; |
- } |
- |
- log = PK11_CreateMergeLog(); |
- if (!log) { |
- rv = SECFailure; |
- SECU_PrintError(progName, "couldn't create error log"); |
- goto merge_fail; |
- } |
- |
- rv = PK11_MergeTokens(slot, sourceSlot, log, &pwdata, &pwdata2); |
- if (rv != SECSuccess) { |
- DumpMergeLog(progName, log); |
- } |
- PK11_DestroyMergeLog(log); |
- |
-merge_fail: |
- SECMOD_CloseUserDB(sourceSlot); |
- PK11_FreeSlot(sourceSlot); |
- goto shutdown; |
- } |
- |
- /* The following 8 options are mutually exclusive with all others. */ |
- |
- /* 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); |
- } |
- goto shutdown; |
- } |
- if (certutil.commands[cmd_DumpChain].activated) { |
- rv = DumpChain(certHandle, name, |
- certutil.options[opt_ASCIIForIO].activated); |
- goto shutdown; |
- } |
- /* XXX needs work */ |
- /* List keys (-K) */ |
- if (certutil.commands[cmd_ListKeys].activated) { |
- rv = ListKeys(slot, name, 0 /*keyindex*/, keytype, PR_FALSE /*dopriv*/, |
- &pwdata); |
- goto shutdown; |
- } |
- /* List modules (-U) */ |
- if (certutil.commands[cmd_ListModules].activated) { |
- rv = ListModules(); |
- goto shutdown; |
- } |
- /* Delete cert (-D) */ |
- if (certutil.commands[cmd_DeleteCert].activated) { |
- rv = DeleteCert(certHandle, name); |
- goto shutdown; |
- } |
- /* Delete key (-F) */ |
- if (certutil.commands[cmd_DeleteKey].activated) { |
- rv = DeleteKey(name, &pwdata); |
- goto shutdown; |
- } |
- /* Modify trust attribute for cert (-M) */ |
- if (certutil.commands[cmd_ModifyCertTrust].activated) { |
- rv = ChangeTrustAttributes(certHandle, slot, name, |
- certutil.options[opt_Trust].arg, &pwdata); |
- goto shutdown; |
- } |
- /* Change key db password (-W) (future - change pw to slot?) */ |
- if (certutil.commands[cmd_ChangePassword].activated) { |
- rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, |
- certutil.options[opt_NewPasswordFile].arg); |
- goto shutdown; |
- } |
- /* Reset the a token */ |
- if (certutil.commands[cmd_TokenReset].activated) { |
- char *sso_pass = ""; |
- |
- if (certutil.options[opt_SSOPass].activated) { |
- sso_pass = certutil.options[opt_SSOPass].arg; |
- } |
- rv = PK11_ResetToken(slot,sso_pass); |
- |
- goto shutdown; |
- } |
- /* Check cert validity against current time (-V) */ |
- if (certutil.commands[cmd_CheckCertValidity].activated) { |
- /* XXX temporary hack for fips - must log in to get priv key */ |
- if (certutil.options[opt_VerifySig].activated) { |
- if (slot && PK11_NeedLogin(slot)) { |
- SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, &pwdata); |
- if (newrv != SECSuccess) { |
- SECU_PrintError(progName, "could not authenticate to token %s.", |
- PK11_GetTokenName(slot)); |
- goto shutdown; |
- } |
- } |
- } |
- rv = ValidateCert(certHandle, name, |
- certutil.options[opt_ValidityTime].arg, |
- certutil.options[opt_Usage].arg, |
- certutil.options[opt_VerifySig].activated, |
- certutil.options[opt_DetailedInfo].activated, |
- certutil.options[opt_ASCIIForIO].activated, |
- &pwdata); |
- if (rv != SECSuccess && PR_GetError() == SEC_ERROR_INVALID_ARGS) |
- SECU_PrintError(progName, "validation failed"); |
- goto shutdown; |
- } |
- |
- /* |
- * Key generation |
- */ |
- |
- /* These commands may require keygen. */ |
- if (certutil.commands[cmd_CertReq].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated || |
- certutil.commands[cmd_GenKeyPair].activated) { |
- if (keysource) { |
- CERTCertificate *keycert; |
- keycert = CERT_FindCertByNicknameOrEmailAddr(certHandle, keysource); |
- if (!keycert) { |
- keycert = PK11_FindCertFromNickname(keysource, NULL); |
- if (!keycert) { |
- SECU_PrintError(progName, |
- "%s is neither a key-type nor a nickname", keysource); |
- return SECFailure; |
- } |
- } |
- privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata); |
- if (privkey) |
- pubkey = CERT_ExtractPublicKey(keycert); |
- if (!pubkey) { |
- SECU_PrintError(progName, |
- "Could not get keys from cert %s", keysource); |
- rv = SECFailure; |
- CERT_DestroyCertificate(keycert); |
- goto shutdown; |
- } |
- keytype = privkey->keyType; |
- /* On CertReq for renewal if no subject has been |
- * specified obtain it from the certificate. |
- */ |
- if (certutil.commands[cmd_CertReq].activated && !subject) { |
- subject = CERT_AsciiToName(keycert->subjectName); |
- if (!subject) { |
- SECU_PrintError(progName, |
- "Could not get subject from certificate %s", keysource); |
- CERT_DestroyCertificate(keycert); |
- rv = SECFailure; |
- goto shutdown; |
- } |
- } |
- CERT_DestroyCertificate(keycert); |
- } else { |
- privkey = |
- CERTUTIL_GeneratePrivateKey(keytype, slot, keysize, |
- publicExponent, |
- certutil.options[opt_NoiseFile].arg, |
- &pubkey, |
- certutil.options[opt_PQGFile].arg, |
- keyAttrFlags, |
- keyOpFlagsOn, |
- keyOpFlagsOff, |
- &pwdata); |
- if (privkey == NULL) { |
- SECU_PrintError(progName, "unable to generate key(s)\n"); |
- rv = SECFailure; |
- goto shutdown; |
- } |
- } |
- privkey->wincx = &pwdata; |
- PORT_Assert(pubkey != NULL); |
- |
- /* If all that was needed was keygen, exit. */ |
- if (certutil.commands[cmd_GenKeyPair].activated) { |
- rv = SECSuccess; |
- goto shutdown; |
- } |
- } |
- |
- /* If we need a list of extensions convert the flags into list format */ |
- if (certutil.commands[cmd_CertReq].activated || |
- certutil.commands[cmd_CreateAndAddCert].activated || |
- certutil.commands[cmd_CreateNewCert].activated) { |
- certutil_extns[ext_keyUsage].activated = |
- certutil.options[opt_AddCmdKeyUsageExt].activated; |
- if (!certutil_extns[ext_keyUsage].activated) { |
- certutil_extns[ext_keyUsage].activated = |
- certutil.options[opt_AddKeyUsageExt].activated; |
- } else { |
- certutil_extns[ext_keyUsage].arg = |
- certutil.options[opt_AddCmdKeyUsageExt].arg; |
- } |
- certutil_extns[ext_basicConstraint].activated = |
- certutil.options[opt_AddBasicConstraintExt].activated; |
- certutil_extns[ext_nameConstraints].activated = |
- certutil.options[opt_AddNameConstraintsExt].activated; |
- certutil_extns[ext_authorityKeyID].activated = |
- certutil.options[opt_AddAuthorityKeyIDExt].activated; |
- certutil_extns[ext_subjectKeyID].activated = |
- certutil.options[opt_AddSubjectKeyIDExt].activated; |
- certutil_extns[ext_CRLDistPts].activated = |
- certutil.options[opt_AddCRLDistPtsExt].activated; |
- certutil_extns[ext_NSCertType].activated = |
- certutil.options[opt_AddCmdNSCertTypeExt].activated; |
- if (!certutil_extns[ext_NSCertType].activated) { |
- certutil_extns[ext_NSCertType].activated = |
- certutil.options[opt_AddNSCertTypeExt].activated; |
- } else { |
- certutil_extns[ext_NSCertType].arg = |
- certutil.options[opt_AddCmdNSCertTypeExt].arg; |
- } |
- |
- certutil_extns[ext_extKeyUsage].activated = |
- certutil.options[opt_AddCmdExtKeyUsageExt].activated; |
- if (!certutil_extns[ext_extKeyUsage].activated) { |
- certutil_extns[ext_extKeyUsage].activated = |
- certutil.options[opt_AddExtKeyUsageExt].activated; |
- } else { |
- 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; |
- certutil_extns[ext_subjInfoAcc].activated = |
- certutil.options[opt_AddSubjInfoAccExt].activated; |
- certutil_extns[ext_certPolicies].activated = |
- certutil.options[opt_AddCertPoliciesExt].activated; |
- certutil_extns[ext_policyMappings].activated = |
- certutil.options[opt_AddPolicyMapExt].activated; |
- certutil_extns[ext_policyConstr].activated = |
- certutil.options[opt_AddPolicyConstrExt].activated; |
- certutil_extns[ext_inhibitAnyPolicy].activated = |
- certutil.options[opt_AddInhibAnyExt].activated; |
- } |
- |
- /* -A -C or -E Read inFile */ |
- if (certutil.commands[cmd_CreateNewCert].activated || |
- certutil.commands[cmd_AddCert].activated || |
- certutil.commands[cmd_AddEmailCert].activated) { |
- PRBool isCreate = certutil.commands[cmd_CreateNewCert].activated; |
- rv = SECU_ReadDERFromFile(isCreate ? &certReqDER : &certDER, inFile, |
- certutil.options[opt_ASCIIForIO].activated, |
- PR_TRUE); |
- if (rv) |
- goto shutdown; |
- } |
- |
- /* |
- * Certificate request |
- */ |
- |
- /* Make a cert request (-R). */ |
- if (certutil.commands[cmd_CertReq].activated) { |
- rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject, |
- certutil.options[opt_PhoneNumber].arg, |
- certutil.options[opt_ASCIIForIO].activated, |
- 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; |
- privkey->wincx = &pwdata; |
- } |
- |
- /* |
- * Certificate creation |
- */ |
- |
- /* If making and adding a cert, create a cert request file first without |
- * any extensions, then load it with the command line extensions |
- * and output the cert to another file. |
- */ |
- if (certutil.commands[cmd_CreateAndAddCert].activated) { |
- static certutilExtnList nullextnlist = {{PR_FALSE, NULL}}; |
- rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject, |
- certutil.options[opt_PhoneNumber].arg, |
- PR_FALSE, /* do not BASE64-encode regardless of -a option */ |
- NULL, |
- NULL, |
- nullextnlist, |
- (certutil.options[opt_GenericExtensions].activated ? |
- certutil.options[opt_GenericExtensions].arg : NULL), |
- &certReqDER); |
- if (rv) |
- goto shutdown; |
- privkey->wincx = &pwdata; |
- } |
- |
- /* Create a certificate (-C or -S). */ |
- if (certutil.commands[cmd_CreateAndAddCert].activated || |
- certutil.commands[cmd_CreateNewCert].activated) { |
- rv = CreateCert(certHandle, slot, |
- certutil.options[opt_IssuerName].arg, |
- &certReqDER, &privkey, &pwdata, hashAlgTag, |
- serialNumber, warpmonths, validityMonths, |
- certutil.options[opt_ExtendedEmailAddrs].arg, |
- certutil.options[opt_ExtendedDNSNames].arg, |
- certutil.options[opt_ASCIIForIO].activated && |
- 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) |
- goto shutdown; |
- } |
- |
- /* |
- * Adding a cert to the database (or slot) |
- */ |
- |
- /* -A -E or -S Add the cert to the DB */ |
- if (certutil.commands[cmd_CreateAndAddCert].activated || |
- certutil.commands[cmd_AddCert].activated || |
- certutil.commands[cmd_AddEmailCert].activated) { |
- if (strstr(certutil.options[opt_Trust].arg, "u")) { |
- fprintf(stderr, "Notice: Trust flag u is set automatically if the " |
- "private key is present.\n"); |
- } |
- rv = AddCert(slot, certHandle, name, |
- certutil.options[opt_Trust].arg, |
- &certDER, |
- certutil.commands[cmd_AddEmailCert].activated,&pwdata); |
- if (rv) |
- goto shutdown; |
- } |
- |
- if (certutil.commands[cmd_CertReq].activated || |
- certutil.commands[cmd_CreateNewCert].activated) { |
- SECItem * item = certutil.commands[cmd_CertReq].activated ? &certReqDER |
- : &certDER; |
- PRInt32 written = PR_Write(outFile, item->data, item->len); |
- if (written < 0 || (PRUint32) written != item->len) { |
- rv = SECFailure; |
- } |
- } |
+ } |
shutdown: |
- if (slot) { |
- PK11_FreeSlot(slot); |
+ if (slot) { |
+ PK11_FreeSlot(slot); |
+ } |
+ if (privkey) { |
+ SECKEY_DestroyPrivateKey(privkey); |
+ } |
+ if (pubkey) { |
+ SECKEY_DestroyPublicKey(pubkey); |
+ } |
+ if (subject) { |
+ CERT_DestroyName(subject); |
+ } |
+ if (name) { |
+ PL_strfree(name); |
+ } |
+ if (inFile && inFile != PR_STDIN) { |
+ PR_Close(inFile); |
+ } |
+ if (outFile && outFile != PR_STDOUT) { |
+ PR_Close(outFile); |
+ } |
+ SECITEM_FreeItem(&certReqDER, PR_FALSE); |
+ SECITEM_FreeItem(&certDER, PR_FALSE); |
+ if (pwdata.data && pwdata.source == PW_PLAINTEXT) { |
+ /* Allocated by a PL_strdup call in SECU_GetModulePassword. */ |
+ PL_strfree(pwdata.data); |
+ } |
+ |
+ /* Open the batch command file. |
+ * |
+ * - If -B <command line> option is specified, the contents in the |
+ * command file will be interpreted as subsequent certutil |
+ * commands to be executed in the current certutil process |
+ * context after the current certutil command has been executed. |
+ * - Each line in the command file consists of the command |
+ * line arguments for certutil. |
+ * - The -d <configdir> option will be ignored if specified in the |
+ * command file. |
+ * - Quoting with double quote characters ("...") is supported |
+ * to allow white space in a command line argument. The |
+ * double quote character cannot be escaped and quoting cannot |
+ * be nested in this version. |
+ * - each line in the batch file is limited to 512 characters |
+ */ |
+ |
+ if ((SECSuccess == rv) && certutil.commands[cmd_Batch].activated) { |
+ FILE *batchFile = NULL; |
+ char *nextcommand = NULL; |
+ PRInt32 cmd_len = 0, buf_size = 0; |
+ static const int increment = 512; |
+ |
+ if (!certutil.options[opt_InputFile].activated || |
+ !certutil.options[opt_InputFile].arg) { |
+ PR_fprintf(PR_STDERR, "%s: no batch input file specified.\n", progName); |
+ return 255; |
} |
- if (privkey) { |
- SECKEY_DestroyPrivateKey(privkey); |
+ batchFile = fopen(certutil.options[opt_InputFile].arg, "r"); |
+ if (!batchFile) { |
+ PR_fprintf(PR_STDERR, |
+ "%s: unable to open \"%s\" for reading (%ld, %ld).\n", |
+ progName, certutil.options[opt_InputFile].arg, PR_GetError(), |
+ PR_GetOSError()); |
+ return 255; |
} |
- if (pubkey) { |
- SECKEY_DestroyPublicKey(pubkey); |
+ /* read and execute command-lines in a loop */ |
+ while (SECSuccess == rv) { |
+ PRBool invalid = PR_FALSE; |
+ int newargc = 2; |
+ char *space = NULL; |
+ char *nextarg = NULL; |
+ char **newargv = NULL; |
+ char *crlf; |
+ |
+ if (cmd_len + increment > buf_size) { |
+ char *new_buf; |
+ buf_size += increment; |
+ new_buf = PORT_Realloc(nextcommand, buf_size); |
+ if (!new_buf) { |
+ PR_fprintf(PR_STDERR, "%s: PORT_Realloc(%ld) failed\n", progName, |
+ buf_size); |
+ break; |
+ } |
+ nextcommand = new_buf; |
+ nextcommand[cmd_len] = '\0'; |
+ } |
+ if (!fgets(nextcommand + cmd_len, buf_size - cmd_len, batchFile)) { |
+ break; |
+ } |
+ crlf = PORT_Strrchr(nextcommand, '\n'); |
+ if (crlf) { |
+ *crlf = '\0'; |
+ } |
+ cmd_len = strlen(nextcommand); |
+ if (cmd_len && nextcommand[cmd_len - 1] == '\\') { |
+ nextcommand[--cmd_len] = '\0'; |
+ continue; |
+ } |
+ |
+ /* we now need to split the command into argc / argv format */ |
+ |
+ newargv = PORT_Alloc(sizeof(char *) * (newargc + 1)); |
+ newargv[0] = progName; |
+ newargv[1] = nextcommand; |
+ nextarg = nextcommand; |
+ while ((space = PORT_Strpbrk(nextarg, " \f\n\r\t\v"))) { |
+ while (isspace(*space)) { |
+ *space = '\0'; |
+ space++; |
+ } |
+ if (*space == '\0') { |
+ break; |
+ } else if (*space != '\"') { |
+ nextarg = space; |
+ } else { |
+ char *closingquote = strchr(space + 1, '\"'); |
+ if (closingquote) { |
+ *closingquote = '\0'; |
+ space++; |
+ nextarg = closingquote + 1; |
+ } else { |
+ invalid = PR_TRUE; |
+ nextarg = space; |
+ } |
+ } |
+ newargc++; |
+ newargv = PORT_Realloc(newargv, sizeof(char *) * (newargc + 1)); |
+ newargv[newargc - 1] = space; |
+ } |
+ newargv[newargc] = NULL; |
+ |
+ /* invoke next command */ |
+ if (PR_TRUE == invalid) { |
+ PR_fprintf( |
+ PR_STDERR, |
+ "Missing closing quote in batch command :\n%s\nNot executed.\n", |
+ nextcommand); |
+ rv = SECFailure; |
+ } else { |
+ if (0 != certutil_main(newargc, newargv, PR_FALSE)) rv = SECFailure; |
+ } |
+ PORT_Free(newargv); |
+ cmd_len = 0; |
+ nextcommand[0] = '\0'; |
} |
- if (subject) { |
- CERT_DestroyName(subject); |
- } |
- if (name) { |
- PL_strfree(name); |
- } |
- if (inFile && inFile != PR_STDIN) { |
- PR_Close(inFile); |
- } |
- if (outFile && outFile != PR_STDOUT) { |
- PR_Close(outFile); |
- } |
- SECITEM_FreeItem(&certReqDER, PR_FALSE); |
- SECITEM_FreeItem(&certDER, PR_FALSE); |
- if (pwdata.data && pwdata.source == PW_PLAINTEXT) { |
- /* Allocated by a PL_strdup call in SECU_GetModulePassword. */ |
- PL_strfree(pwdata.data); |
- } |
+ PORT_Free(nextcommand); |
+ fclose(batchFile); |
+ } |
- /* Open the batch command file. |
- * |
- * - If -B <command line> option is specified, the contents in the |
- * command file will be interpreted as subsequent certutil |
- * commands to be executed in the current certutil process |
- * context after the current certutil command has been executed. |
- * - Each line in the command file consists of the command |
- * line arguments for certutil. |
- * - The -d <configdir> option will be ignored if specified in the |
- * command file. |
- * - Quoting with double quote characters ("...") is supported |
- * to allow white space in a command line argument. The |
- * double quote character cannot be escaped and quoting cannot |
- * be nested in this version. |
- * - each line in the batch file is limited to 512 characters |
- */ |
- |
- if ((SECSuccess == rv) && certutil.commands[cmd_Batch].activated) { |
- FILE* batchFile = NULL; |
- char *nextcommand = NULL; |
- PRInt32 cmd_len = 0, buf_size = 0; |
- static const int increment = 512; |
- |
- if (!certutil.options[opt_InputFile].activated || |
- !certutil.options[opt_InputFile].arg) { |
- PR_fprintf(PR_STDERR, |
- "%s: no batch input file specified.\n", |
- progName); |
- return 255; |
- } |
- batchFile = fopen(certutil.options[opt_InputFile].arg, "r"); |
- if (!batchFile) { |
- PR_fprintf(PR_STDERR, |
- "%s: unable to open \"%s\" for reading (%ld, %ld).\n", |
- progName, certutil.options[opt_InputFile].arg, |
- PR_GetError(), PR_GetOSError()); |
- return 255; |
- } |
- /* read and execute command-lines in a loop */ |
- while ( SECSuccess == rv ) { |
- PRBool invalid = PR_FALSE; |
- int newargc = 2; |
- char* space = NULL; |
- char* nextarg = NULL; |
- char** newargv = NULL; |
- char* crlf; |
- |
- if (cmd_len + increment > buf_size) { |
- char * new_buf; |
- buf_size += increment; |
- new_buf = PORT_Realloc(nextcommand, buf_size); |
- if (!new_buf) { |
- PR_fprintf(PR_STDERR, "%s: PORT_Realloc(%ld) failed\n", |
- progName, buf_size); |
- break; |
- } |
- nextcommand = new_buf; |
- nextcommand[cmd_len] = '\0'; |
- } |
- if (!fgets(nextcommand + cmd_len, buf_size - cmd_len, batchFile)) { |
- break; |
- } |
- crlf = PORT_Strrchr(nextcommand, '\n'); |
- if (crlf) { |
- *crlf = '\0'; |
- } |
- cmd_len = strlen(nextcommand); |
- if (cmd_len && nextcommand[cmd_len - 1] == '\\') { |
- nextcommand[--cmd_len] = '\0'; |
- continue; |
- } |
- |
- /* we now need to split the command into argc / argv format */ |
- |
- newargv = PORT_Alloc(sizeof(char*)*(newargc+1)); |
- newargv[0] = progName; |
- newargv[1] = nextcommand; |
- nextarg = nextcommand; |
- while ((space = PORT_Strpbrk(nextarg, " \f\n\r\t\v")) ) { |
- while (isspace(*space) ) { |
- *space = '\0'; |
- space ++; |
- } |
- if (*space == '\0') { |
- break; |
- } else if (*space != '\"') { |
- nextarg = space; |
- } else { |
- char* closingquote = strchr(space+1, '\"'); |
- if (closingquote) { |
- *closingquote = '\0'; |
- space++; |
- nextarg = closingquote+1; |
- } else { |
- invalid = PR_TRUE; |
- nextarg = space; |
- } |
- } |
- newargc++; |
- newargv = PORT_Realloc(newargv, sizeof(char*)*(newargc+1)); |
- newargv[newargc-1] = space; |
- } |
- newargv[newargc] = NULL; |
- |
- /* invoke next command */ |
- if (PR_TRUE == invalid) { |
- PR_fprintf(PR_STDERR, "Missing closing quote in batch command :\n%s\nNot executed.\n", |
- nextcommand); |
- rv = SECFailure; |
- } else { |
- if (0 != certutil_main(newargc, newargv, PR_FALSE) ) |
- rv = SECFailure; |
- } |
- PORT_Free(newargv); |
- cmd_len = 0; |
- nextcommand[0] = '\0'; |
- } |
- PORT_Free(nextcommand); |
- fclose(batchFile); |
- } |
- |
- if ((initialized == PR_TRUE) && NSS_Shutdown() != SECSuccess) { |
- exit(1); |
- } |
- if (rv == SECSuccess) { |
- return 0; |
- } else { |
- return 255; |
- } |
+ if ((initialized == PR_TRUE) && NSS_Shutdown() != SECSuccess) { |
+ exit(1); |
+ } |
+ if (rv == SECSuccess) { |
+ return 0; |
+ } else { |
+ return 255; |
+ } |
} |
-int |
-main(int argc, char **argv) |
-{ |
- int rv = certutil_main(argc, argv, PR_TRUE); |
- PL_ArenaFinish(); |
- PR_Cleanup(); |
- return rv; |
+int main(int argc, char **argv) { |
+ int rv = certutil_main(argc, argv, PR_TRUE); |
+ PL_ArenaFinish(); |
+ PR_Cleanup(); |
+ return rv; |
} |
- |