summaryrefslogtreecommitdiffstats
path: root/security/nss/cmd/lib/secutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/cmd/lib/secutil.c')
-rw-r--r--security/nss/cmd/lib/secutil.c236
1 files changed, 208 insertions, 28 deletions
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index 97c7f750a..703845e98 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -22,6 +22,7 @@
#include <stdarg.h>
#include <sys/stat.h>
#include <errno.h>
+#include <limits.h>
#ifdef XP_UNIX
#include <unistd.h>
@@ -1107,36 +1108,33 @@ typedef struct secuPBEParamsStr {
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
/* SECOID_PKCS5_PBKDF2 */
-const SEC_ASN1Template secuKDF2Params[] =
- {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
- { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
- { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
- { SEC_ASN1_INTEGER, offsetof(secuPBEParams, keyLength) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
- };
+const SEC_ASN1Template secuKDF2Params[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, keyLength) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { 0 }
+};
/* PKCS5v1 & PKCS12 */
-const SEC_ASN1Template secuPBEParamsTemp[] =
- {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
- { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
- { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
- { 0 }
- };
+const SEC_ASN1Template secuPBEParamsTemp[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
+ { 0 }
+};
/* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
-const SEC_ASN1Template secuPBEV2Params[] =
- {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, cipherAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
- };
+const SEC_ASN1Template secuPBEV2Params[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, cipherAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { 0 }
+};
void
secu_PrintRSAPSSParams(FILE *out, SECItem *value, char *m, int level)
@@ -2299,8 +2297,9 @@ SECU_PrintCertAttributes(FILE *out, CERTAttribute **attrs, char *m, int level)
return rv;
}
-int /* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
- SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
+/* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
+int
+SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
{
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
CERTCertificateRequest *cr;
@@ -3250,6 +3249,26 @@ SEC_PrintCertificateAndTrust(CERTCertificate *cert,
"Certificate Trust Flags", 1);
}
+ /* The distrust fields are hard-coded in nssckbi and read-only.
+ * If verifying some cert, with vfychain, for instance, the certificate may
+ * not have a defined slot if not imported. */
+ if (cert->slot != NULL && cert->distrust != NULL) {
+ const unsigned int kDistrustFieldSize = 13;
+ fprintf(stdout, "\n");
+ SECU_Indent(stdout, 1);
+ fprintf(stdout, "%s:\n", "Certificate Distrust Dates");
+ if (cert->distrust->serverDistrustAfter.len == kDistrustFieldSize) {
+ SECU_PrintTimeChoice(stdout,
+ &cert->distrust->serverDistrustAfter,
+ "Server Distrust After", 2);
+ }
+ if (cert->distrust->emailDistrustAfter.len == kDistrustFieldSize) {
+ SECU_PrintTimeChoice(stdout,
+ &cert->distrust->emailDistrustAfter,
+ "E-mail Distrust After", 2);
+ }
+ }
+
printf("\n");
return (SECSuccess);
@@ -3979,3 +3998,164 @@ done:
*enabledSigSchemes = schemes;
return SECSuccess;
}
+
+/* Parse the exporter spec in the form: LABEL[:OUTPUT-LENGTH[:CONTEXT]] */
+static SECStatus
+parseExporter(const char *arg,
+ secuExporter *exporter)
+{
+ SECStatus rv = SECSuccess;
+
+ char *str = PORT_Strdup(arg);
+ if (!str) {
+ rv = SECFailure;
+ goto done;
+ }
+
+ char *labelEnd = strchr(str, ':');
+ if (labelEnd) {
+ *labelEnd = '\0';
+ labelEnd++;
+
+ /* To extract CONTEXT, first skip OUTPUT-LENGTH */
+ char *outputEnd = strchr(labelEnd, ':');
+ if (outputEnd) {
+ *outputEnd = '\0';
+ outputEnd++;
+
+ exporter->hasContext = PR_TRUE;
+ exporter->context.data = (unsigned char *)PORT_Strdup(outputEnd);
+ exporter->context.len = strlen(outputEnd);
+ if (PORT_Strncasecmp((char *)exporter->context.data, "0x", 2) == 0) {
+ rv = SECU_SECItemHexStringToBinary(&exporter->context);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (labelEnd && *labelEnd != '\0') {
+ long int outputLength = strtol(labelEnd, NULL, 10);
+ if (!(outputLength > 0 && outputLength <= UINT_MAX)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ goto done;
+ }
+ exporter->outputLength = outputLength;
+ } else {
+ exporter->outputLength = 20;
+ }
+
+ char *label = PORT_Strdup(str);
+ exporter->label.data = (unsigned char *)label;
+ exporter->label.len = strlen(label);
+ if (PORT_Strncasecmp((char *)exporter->label.data, "0x", 2) == 0) {
+ rv = SECU_SECItemHexStringToBinary(&exporter->label);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ }
+
+done:
+ PORT_Free(str);
+
+ return rv;
+}
+
+SECStatus
+parseExporters(const char *arg,
+ const secuExporter **enabledExporters,
+ unsigned int *enabledExporterCount)
+{
+ secuExporter *exporters;
+ unsigned int numValues = 0;
+ unsigned int count = 0;
+
+ if (countItems(arg, &numValues) != SECSuccess) {
+ return SECFailure;
+ }
+ exporters = PORT_ZNewArray(secuExporter, numValues);
+ if (!exporters) {
+ return SECFailure;
+ }
+
+ /* Get exporter definitions. */
+ char *str = PORT_Strdup(arg);
+ if (!str) {
+ goto done;
+ }
+ char *p = strtok(str, ",");
+ while (p) {
+ SECStatus rv = parseExporter(p, &exporters[count++]);
+ if (rv != SECSuccess) {
+ count = 0;
+ goto done;
+ }
+ p = strtok(NULL, ",");
+ }
+
+done:
+ PORT_Free(str);
+ if (!count) {
+ PORT_Free(exporters);
+ return SECFailure;
+ }
+
+ *enabledExporterCount = count;
+ *enabledExporters = exporters;
+ return SECSuccess;
+}
+
+static SECStatus
+exportKeyingMaterial(PRFileDesc *fd, const secuExporter *exporter)
+{
+ SECStatus rv = SECSuccess;
+ unsigned char *out = PORT_Alloc(exporter->outputLength);
+
+ if (!out) {
+ fprintf(stderr, "Unable to allocate buffer for keying material\n");
+ return SECFailure;
+ }
+ rv = SSL_ExportKeyingMaterial(fd,
+ (char *)exporter->label.data,
+ exporter->label.len,
+ exporter->hasContext,
+ exporter->context.data,
+ exporter->context.len,
+ out,
+ exporter->outputLength);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ fprintf(stdout, "Exported Keying Material:\n");
+ secu_PrintRawString(stdout, (SECItem *)&exporter->label, "Label", 1);
+ if (exporter->hasContext) {
+ SECU_PrintAsHex(stdout, &exporter->context, "Context", 1);
+ }
+ SECU_Indent(stdout, 1);
+ fprintf(stdout, "Length: %u\n", exporter->outputLength);
+ SECItem temp = { siBuffer, out, exporter->outputLength };
+ SECU_PrintAsHex(stdout, &temp, "Keying Material", 1);
+
+done:
+ PORT_Free(out);
+ return rv;
+}
+
+SECStatus
+exportKeyingMaterials(PRFileDesc *fd,
+ const secuExporter *exporters,
+ unsigned int exporterCount)
+{
+ unsigned int i;
+
+ for (i = 0; i < exporterCount; i++) {
+ SECStatus rv = exportKeyingMaterial(fd, &exporters[i]);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+
+ return SECSuccess;
+}