summaryrefslogtreecommitdiff
path: root/security/nss/cmd/lib
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/cmd/lib')
-rw-r--r--security/nss/cmd/lib/Makefile75
-rw-r--r--security/nss/cmd/lib/NSPRerrs.h150
-rw-r--r--security/nss/cmd/lib/SECerrs.h442
-rw-r--r--security/nss/cmd/lib/SSLerrs.h366
-rw-r--r--security/nss/cmd/lib/berparse.c404
-rw-r--r--security/nss/cmd/lib/config.mk43
-rw-r--r--security/nss/cmd/lib/derprint.c619
-rw-r--r--security/nss/cmd/lib/dongle.c249
-rw-r--r--security/nss/cmd/lib/fe_util.c40
-rw-r--r--security/nss/cmd/lib/ffs.c48
-rw-r--r--security/nss/cmd/lib/filestub.c1118
-rw-r--r--security/nss/cmd/lib/makefile.win66
-rw-r--r--security/nss/cmd/lib/manifest.mn68
-rw-r--r--security/nss/cmd/lib/secarb.c372
-rw-r--r--security/nss/cmd/lib/seccnames.c204
-rw-r--r--security/nss/cmd/lib/secerror.c107
-rw-r--r--security/nss/cmd/lib/secpwd.c193
-rw-r--r--security/nss/cmd/lib/secutil.c2593
-rw-r--r--security/nss/cmd/lib/secutil.h327
-rw-r--r--security/nss/cmd/lib/sslstubs.c74
-rw-r--r--security/nss/cmd/lib/strerror.c127
-rw-r--r--security/nss/cmd/lib/stubs.c50
22 files changed, 7735 insertions, 0 deletions
diff --git a/security/nss/cmd/lib/Makefile b/security/nss/cmd/lib/Makefile
new file mode 100644
index 000000000..0769c80a3
--- /dev/null
+++ b/security/nss/cmd/lib/Makefile
@@ -0,0 +1,75 @@
+#! gmake
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include config.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
diff --git a/security/nss/cmd/lib/NSPRerrs.h b/security/nss/cmd/lib/NSPRerrs.h
new file mode 100644
index 000000000..5e2cd793e
--- /dev/null
+++ b/security/nss/cmd/lib/NSPRerrs.h
@@ -0,0 +1,150 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+/* General NSPR 2.0 errors */
+/* Caller must #include "prerror.h" */
+
+ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
+ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
+ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
+ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
+ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
+ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
+ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
+ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
+ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
+ER2( PR_IO_ERROR, "I/O function error." )
+ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
+ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
+ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
+ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
+ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
+ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
+ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
+ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
+ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
+ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
+ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
+ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
+ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
+ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
+ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
+ER2( PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries." )
+ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
+ER2( PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed." )
+ER2( PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range." )
+ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
+ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
+ER2( PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor." )
+ER2( PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor." )
+ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
+ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
+ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform." )
+ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested." )
+ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
+ER2( PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided." )
+ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
+ER2( PR_RANGE_ERROR, "Unused." )
+ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
+ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
+ER2( PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows." )
+ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
+ER2( PR_PIPE_ERROR, "Unused." )
+ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
+ER2( PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory." )
+ER2( PR_LOOP_ERROR, "Symbolic link loop." )
+ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
+ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
+ER2( PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file." )
+ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system." )
+ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty." )
+ER2( PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy." )
+ER2( PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device." )
+ER2( PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted." )
+ER2( PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists." )
+ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
+"Directory is full. No additional filenames may be added." )
+ER2( PR_INVALID_DEVICE_STATE_ERROR,
+"The required device was in an invalid state." )
+ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
+ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
+ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
+ER2( PR_FILE_SEEK_ERROR, "Seek error." )
+ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
+ER2( PR_IN_PROGRESS_ERROR,
+"Operation is still in progress (probably a non-blocking connect)." )
+ER2( PR_ALREADY_INITIATED_ERROR,
+"Operation has already been initiated (probably a non-blocking connect)." )
+
+#ifdef PR_GROUP_EMPTY_ERROR
+ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
+#endif
+
+#ifdef PR_INVALID_STATE_ERROR
+ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
+#endif
+
+#ifdef PR_NETWORK_DOWN_ERROR
+ER2( PR_NETWORK_DOWN_ERROR, "Network is down." )
+#endif
+
+#ifdef PR_SOCKET_SHUTDOWN_ERROR
+ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." )
+#endif
+
+#ifdef PR_CONNECT_ABORTED_ERROR
+ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." )
+#endif
+
+#ifdef PR_HOST_UNREACHABLE_ERROR
+ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." )
+#endif
+
+/* always last */
+ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
diff --git a/security/nss/cmd/lib/SECerrs.h b/security/nss/cmd/lib/SECerrs.h
new file mode 100644
index 000000000..41bb03101
--- /dev/null
+++ b/security/nss/cmd/lib/SECerrs.h
@@ -0,0 +1,442 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/* General security error codes */
+/* Caller must #include "secerr.h" */
+
+ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
+"An I/O error occurred during security authorization.")
+
+ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
+"security library failure.")
+
+ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
+"security library: received bad data.")
+
+ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
+"security library: output length error.")
+
+ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
+"security library has experienced an input length error.")
+
+ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
+"security library: invalid arguments.")
+
+ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
+"security library: invalid algorithm.")
+
+ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
+"security library: invalid AVA.")
+
+ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
+"Improperly formatted time string.")
+
+ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
+"security library: improperly formatted DER-encoded message.")
+
+ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
+"Peer's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
+"Peer's Certificate has expired.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
+"Peer's Certificate has been revoked.")
+
+ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
+"Peer's Certificate issuer is not recognized.")
+
+ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
+"Peer's public key is invalid.")
+
+ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
+"The security password entered is incorrect.")
+
+ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
+"New password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
+"security library: no nodelock.")
+
+ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
+"security library: bad database.")
+
+ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
+"security library: memory allocation failure.")
+
+ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
+"Peer's certificate issuer has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
+"Peer's certificate has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
+"Certificate already exists in your database.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
+"Downloaded certificate's name duplicates one already in your database.")
+
+ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
+"Error adding certificate to database.")
+
+ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
+"Error refiling the key for this certificate.")
+
+ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
+"The private key for this certificate cannot be found in key database")
+
+ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
+"This certificate is valid.")
+
+ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
+"This certificate is not valid.")
+
+ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
+"Cert Library: No Response")
+
+ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
+"The certificate issuer's certificate has expired. Check your system date and time.")
+
+ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
+"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
+
+ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
+"The CRL for the certificate's issuer has an invalid signature.")
+
+ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
+"New CRL has an invalid format.")
+
+ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
+"Certificate extension value is invalid.")
+
+ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
+"Certificate extension not found.")
+
+ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
+"Issuer certificate is invalid.")
+
+ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
+"Certificate path length constraint is invalid.")
+
+ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
+"Certificate usages field is invalid.")
+
+ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
+"**Internal ONLY module**")
+
+ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
+"The key does not support the requested operation.")
+
+ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
+"Certificate contains unknown critical extension.")
+
+ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
+"New CRL is not later than the current one.")
+
+ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
+"Not encrypted or signed: you do not yet have an email certificate.")
+
+ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
+"Not encrypted: you do not have certificates for each of the recipients.")
+
+ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
+"Cannot decrypt: you are not a recipient, or matching certificate and \
+private key not found.")
+
+ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
+"Cannot decrypt: key encryption algorithm does not match your certificate.")
+
+ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
+"Signature verification failed: no signer found, too many signers found, \
+or improper or corrupted data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
+"Unsupported or unknown key algorithm.")
+
+ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
+"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
+
+
+/* Fortezza Alerts */
+ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
+"Fortezza card has not been properly initialized. \
+Please remove it and return it to your issuer.")
+
+ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
+"No Fortezza cards Found")
+
+ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
+"No Fortezza card selected")
+
+ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
+"Please select a personality to get more info on")
+
+ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
+"Personality not found")
+
+ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
+"No more information on that Personality")
+
+ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
+"Invalid Pin")
+
+ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
+"Couldn't initialize Fortezza personalities.")
+/* end fortezza alerts. */
+
+ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
+"No KRL for this site's certificate has been found.")
+
+ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
+"The KRL for this site's certificate has expired.")
+
+ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
+"The KRL for this site's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
+"The key for this site's certificate has been revoked.")
+
+ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
+"New KRL has an invalid format.")
+
+ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
+"security library: need random data.")
+
+ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
+"security library: no security module can perform the requested operation.")
+
+ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
+"The security card or token does not exist, needs to be initialized, or has been removed.")
+
+ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
+"security library: read-only database.")
+
+ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
+"No slot or token was selected.")
+
+ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
+"A certificate with the same nickname already exists.")
+
+ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
+"A key with the same nickname already exists.")
+
+ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
+"error while creating safe object")
+
+ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
+"error while creating baggage object")
+
+ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
+"Couldn't remove the principal")
+
+ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
+"Couldn't delete the privilege")
+
+ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
+"This principal doesn't have a certificate")
+
+ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
+"Required algorithm is not allowed.")
+
+ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
+"Error attempting to export certificates.")
+
+ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
+"Error attempting to import certificates.")
+
+ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
+"Unable to import. Decoding error. File not valid.")
+
+ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
+"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
+"Unable to import. MAC algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
+"Unable to import. Only password integrity and privacy modes supported.")
+
+ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
+"Unable to import. File structure is corrupt.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
+"Unable to import. Encryption algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
+"Unable to import. File version not supported.")
+
+ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
+"Unable to import. Incorrect privacy password.")
+
+ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
+"Unable to import. Same nickname already exists in database.")
+
+ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
+"The user pressed cancel.")
+
+ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
+"Not imported, already in database.")
+
+ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
+"Message not sent.")
+
+ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
+"Certificate key usage inadequate for attempted operation.")
+
+ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
+"Certificate type not approved for application.")
+
+ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
+"Address in signing certificate does not match address in message headers.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
+"Unable to import. Error attempting to import private key.")
+
+ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
+"Unable to import. Error attempting to import certificate chain.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
+"Unable to export. Unable to locate certificate or key by nickname.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
+"Unable to export. Private Key could not be located and exported.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
+"Unable to export. Unable to write the export file.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
+"Unable to import. Unable to read the import file.")
+
+ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
+"Unable to export. Key database corrupt or deleted.")
+
+ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
+"Unable to generate public/private key pair.")
+
+ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
+"Password entered is invalid. Please pick a different one.")
+
+ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
+"Old password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
+"Certificate nickname already in use.")
+
+ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
+"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
+
+ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105),
+"A sensitive key cannot be moved to the slot where it is needed.")
+
+ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
+"Invalid module name.")
+
+ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
+"Invalid module path/filename")
+
+ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
+"Unable to add module")
+
+ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
+"Unable to delete module")
+
+ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
+"New KRL is not later than the current one.")
+
+ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
+"New CKL has different issuer than current CKL. Delete current CKL.")
+
+ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
+"The Certifying Authority for this certificate is not permitted to issue a \
+certificate with this name.")
+
+ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
+"The key revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
+"The certificate revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
+"The requested certificate could not be found.")
+
+ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
+"The signer's certificate could not be found.")
+
+ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
+"The location for the certificate status server has invalid format.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
+"The OCSP response cannot be fully decoded; it is of an unknown type.")
+
+ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
+"The OCSP server returned unexpected/invalid HTTP data.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
+"The OCSP server found the request to be corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
+"The OCSP server experienced an internal error.")
+
+ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
+"The OCSP server suggests trying again later.")
+
+ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
+"The OCSP server requires a signature on this request.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
+"The OCSP server has refused this request as unauthorized.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
+"The OCSP server returned an unrecognizable status.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
+"The OCSP server has no status for the certificate.")
+
+ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
+"You must enable OCSP before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
+"You must set the OCSP default responder before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
+"The response from the OCSP server was corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
+"The signer of the OCSP response is not authorized to give status for \
+this certificate.")
+
+ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
+"The OCSP response is not yet valid (contains a date in the future).")
+
+ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
+"The OCSP response contains out-of-date information.")
diff --git a/security/nss/cmd/lib/SSLerrs.h b/security/nss/cmd/lib/SSLerrs.h
new file mode 100644
index 000000000..06803b849
--- /dev/null
+++ b/security/nss/cmd/lib/SSLerrs.h
@@ -0,0 +1,366 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/* SSL-specific security error codes */
+/* caller must include "sslerr.h" */
+
+ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
+"Unable to communicate securely. Peer does not support high-grade encryption.")
+
+ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
+"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
+
+ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
+"Cannot communicate securely with peer: no common encryption algorithm(s).")
+
+ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
+"Unable to find the certificate or key necessary for authentication.")
+
+ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
+"Unable to communicate securely with peer: peers's certificate was rejected.")
+
+/* unused (SSL_ERROR_BASE + 5),*/
+
+ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
+"The server has encountered bad data from the client.")
+
+ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
+"The client has encountered bad data from the server.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
+"Unsupported certificate type.")
+
+ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
+"Peer using unsupported version of security protocol.")
+
+/* unused (SSL_ERROR_BASE + 10),*/
+
+ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
+"Client authentication failed: private key in key database does not match public key in certificate database.")
+
+ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
+"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
+
+/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
+ defined in sslerr.h
+*/
+
+ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
+"Peer only supports SSL version 2, which is locally disabled.")
+
+
+ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
+"SSL received a record with an incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
+"SSL peer reports incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
+"SSL peer cannot verify your certificate.")
+
+ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
+"SSL peer rejected your certificate as revoked.")
+
+ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
+"SSL peer rejected your certificate as expired.")
+
+ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
+"Cannot connect: SSL is disabled.")
+
+ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
+"Cannot connect: SSL peer is in another FORTEZZA domain.")
+
+
+ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
+"An unknown SSL cipher suite has been requested.")
+
+ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
+"No cipher suites are present and enabled in this program.")
+
+ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
+"SSL received a record with bad block padding.")
+
+ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
+"SSL received a record that exceeded the maximum permissible length.")
+
+ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
+"SSL attempted to send a record that exceeded the maximum permissible length.")
+
+/*
+ * Received a malformed (too long or short or invalid content) SSL handshake.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
+"SSL received a malformed Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
+"SSL received a malformed Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
+"SSL received a malformed Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
+"SSL received a malformed Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
+"SSL received a malformed Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
+"SSL received a malformed Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
+"SSL received a malformed Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
+"SSL received a malformed Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
+"SSL received a malformed Client Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
+"SSL received a malformed Finished handshake message.")
+
+/*
+ * Received a malformed (too long or short) SSL record.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
+"SSL received a malformed Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
+"SSL received a malformed Alert record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
+"SSL received a malformed Handshake record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
+"SSL received a malformed Application Data record.")
+
+/*
+ * Received an SSL handshake that was inappropriate for the state we're in.
+ * E.g. Server received message from server, or wrong state in state machine.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
+"SSL received an unexpected Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
+"SSL received an unexpected Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
+"SSL received an unexpected Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
+"SSL received an unexpected Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
+"SSL received an unexpected Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
+"SSL received an unexpected Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
+"SSL received an unexpected Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
+"SSL received an unexpected Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
+"SSL received an unexpected Cllient Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
+"SSL received an unexpected Finished handshake message.")
+
+/*
+ * Received an SSL record that was inappropriate for the state we're in.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
+"SSL received an unexpected Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
+"SSL received an unexpected Alert record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
+"SSL received an unexpected Handshake record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
+"SSL received an unexpected Application Data record.")
+
+/*
+ * Received record/message with unknown discriminant.
+ */
+ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
+"SSL received a record with an unknown content type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
+"SSL received a handshake message with an unknown message type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
+"SSL received an alert record with an unknown alert description.")
+
+/*
+ * Received an alert reporting what we did wrong. (more alerts above)
+ */
+ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
+"SSL peer has closed this connection.")
+
+ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
+"SSL peer was not expecting a handshake message it received.")
+
+ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
+"SSL peer was unable to succesfully decompress an SSL record it received.")
+
+ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
+"SSL peer was unable to negotiate an acceptable set of security parameters.")
+
+ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
+"SSL peer rejected a handshake message for unacceptable content.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
+"SSL peer does not support certificates of the type it received.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
+"SSL peer had some unspecified issue with the certificate it received.")
+
+
+ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
+"SSL experienced a failure of its random number generator.")
+
+ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
+"Unable to digitally sign data required to verify your certificate.")
+
+ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
+"SSL was unable to extract the public key from the peer's certificate.")
+
+ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
+"Unspecified failure while processing SSL Server Key Exchange handshake.")
+
+ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
+"Unspecified failure while processing SSL Client Key Exchange handshake.")
+
+ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
+"Bulk data encryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
+"Bulk data decryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
+"Attempt to write encrypted data to underlying socket failed.")
+
+ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
+"MD5 digest function failed.")
+
+ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
+"SHA-1 digest function failed.")
+
+ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
+"MAC computation failed.")
+
+ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
+"Failure to create Symmetric Key context.")
+
+ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
+"Failure to unwrap the Symmetric key in Client Key Exchange message.")
+
+ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
+"SSL Server attempted to use domestic-grade public key with export cipher suite.")
+
+ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
+"PKCS11 code failed to translate an IV into a param.")
+
+ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
+"Failed to initialize the selected cipher suite.")
+
+ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
+"Client failed to generate session keys for SSL session.")
+
+ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
+"Server has no key for the attempted key exchange algorithm.")
+
+ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
+"PKCS#11 token was inserted or removed while operation was in progress.")
+
+ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
+"No PKCS#11 token could be found to do a required operation.")
+
+ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
+"Cannot communicate securely with peer: no common compression algorithm(s).")
+
+ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
+"Cannot initiate another SSL handshake until current handshake is complete.")
+
+ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
+"Received incorrect handshakes hash values from peer.")
+
+ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
+"The certificate provided cannot be used with the selected key exchange algorithm.")
+
+ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
+"No certificate authority is trusted for SSL client authentication.")
+
+ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
+"Client's SSL session ID not found in server's session cache.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
+"Peer was unable to decrypt an SSL record it received.")
+
+ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
+"Peer received an SSL record that was longer than is permitted.")
+
+ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
+"Peer does not recognize and trust the CA that issued your certificate.")
+
+ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
+"Peer received a valid certificate, but access was denied.")
+
+ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
+"Peer could not decode an SSL handshake message.")
+
+ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
+"Peer reports failure of signature verification or key exchange.")
+
+ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
+"Peer reports negotiation not in compliance with export regulations.")
+
+ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
+"Peer reports incompatible or unsupported protocol version.")
+
+ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
+"Server requires ciphers more secure than those supported by client.")
+
+ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
+"Peer reports it experienced an internal error.")
+
+ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
+"Peer user canceled handshake.")
+
+ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
+"Peer does not permit renegotiation of SSL security parameters.")
+
diff --git a/security/nss/cmd/lib/berparse.c b/security/nss/cmd/lib/berparse.c
new file mode 100644
index 000000000..c040ab2b1
--- /dev/null
+++ b/security/nss/cmd/lib/berparse.c
@@ -0,0 +1,404 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secutil.h"
+
+typedef enum {
+ tagDone, lengthDone, leafDone, compositeDone,
+ notDone,
+ parseError, parseComplete
+} ParseState;
+
+typedef unsigned char Byte;
+typedef void (*ParseProc)(BERParse *h, unsigned char **buf, int *len);
+typedef struct {
+ SECArb arb;
+ int pos; /* length from global start to item start */
+ SECArb *parent;
+} ParseStackElem;
+
+struct BERParseStr {
+ PRArenaPool *his;
+ PRArenaPool *mine;
+ ParseProc proc;
+ int stackDepth;
+ ParseStackElem *stackPtr;
+ ParseStackElem *stack;
+ int pending; /* bytes remaining to complete this part */
+ int pos; /* running length of consumed characters */
+ ParseState state;
+ PRBool keepLeaves;
+ PRBool derOnly;
+ BERFilterProc filter;
+ void *filterArg;
+ BERNotifyProc before;
+ void *beforeArg;
+ BERNotifyProc after;
+ void *afterArg;
+};
+
+#define UNKNOWN -1
+
+static unsigned char NextChar(BERParse *h, unsigned char **buf, int *len)
+{
+ unsigned char c = *(*buf)++;
+ (*len)--;
+ h->pos++;
+ if (h->filter)
+ (*h->filter)(h->filterArg, &c, 1);
+ return c;
+}
+
+static void ParseTag(BERParse *h, unsigned char **buf, int *len)
+{
+ SECArb* arb = &(h->stackPtr->arb);
+ arb->tag = NextChar(h, buf, len);
+
+ PORT_Assert(h->state == notDone);
+
+ /*
+ * NOTE: This does not handle the high-tag-number form
+ */
+ if ((arb->tag & DER_HIGH_TAG_NUMBER) == DER_HIGH_TAG_NUMBER) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return;
+ }
+
+ h->pending = UNKNOWN;
+ arb->length = UNKNOWN;
+ if (arb->tag & DER_CONSTRUCTED) {
+ arb->body.cons.numSubs = 0;
+ arb->body.cons.subs = NULL;
+ } else {
+ arb->body.item.len = UNKNOWN;
+ arb->body.item.data = NULL;
+ }
+
+ h->state = tagDone;
+}
+
+static void ParseLength(BERParse *h, unsigned char **buf, int *len)
+{
+ Byte b;
+ SECArb *arb = &(h->stackPtr->arb);
+
+ PORT_Assert(h->state == notDone);
+
+ if (h->pending == UNKNOWN) {
+ b = NextChar(h, buf, len);
+ if ((b & 0x80) == 0) { /* short form */
+ arb->length = b;
+ /*
+ * if the tag and the length are both zero bytes, then this
+ * should be the marker showing end of list for the
+ * indefinite length composite
+ */
+ if (arb->length == 0 && arb->tag == 0)
+ h->state = compositeDone;
+ else
+ h->state = lengthDone;
+ return;
+ }
+
+ h->pending = b & 0x7f;
+ /* 0 implies this is an indefinite length */
+ if (h->pending > 4) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return;
+ }
+ arb->length = 0;
+ }
+
+ while ((*len > 0) && (h->pending > 0)) {
+ b = NextChar(h, buf, len);
+ arb->length = (arb->length << 8) + b;
+ h->pending--;
+ }
+ if (h->pending == 0) {
+ if (h->derOnly && (arb->length == 0))
+ h->state = parseError;
+ else
+ h->state = lengthDone;
+ }
+ return;
+}
+
+static void ParseLeaf(BERParse *h, unsigned char **buf, int *len)
+{
+ int count;
+ SECArb *arb = &(h->stackPtr->arb);
+
+ PORT_Assert(h->state == notDone);
+ PORT_Assert(h->pending >= 0);
+
+ if (*len < h->pending)
+ count = *len;
+ else
+ count = h->pending;
+
+ if (h->keepLeaves)
+ memcpy(arb->body.item.data + arb->body.item.len, *buf, count);
+ if (h->filter)
+ (*h->filter)(h->filterArg, *buf, count);
+ *buf += count;
+ *len -= count;
+ arb->body.item.len += count;
+ h->pending -= count;
+ h->pos += count;
+ if (h->pending == 0) {
+ h->state = leafDone;
+ }
+ return;
+}
+
+static void CreateArbNode(BERParse *h)
+{
+ SECArb *arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
+
+ *arb = h->stackPtr->arb;
+
+ /*
+ * Special case closing the root
+ */
+ if (h->stackPtr == h->stack) {
+ PORT_Assert(arb->tag & DER_CONSTRUCTED);
+ h->state = parseComplete;
+ } else {
+ SECArb *parent = h->stackPtr->parent;
+ parent->body.cons.subs = DS_ArenaGrow(
+ h->his, parent->body.cons.subs,
+ (parent->body.cons.numSubs) * sizeof(SECArb*),
+ (parent->body.cons.numSubs + 1) * sizeof(SECArb*));
+ parent->body.cons.subs[parent->body.cons.numSubs] = arb;
+ parent->body.cons.numSubs++;
+ h->proc = ParseTag;
+ h->state = notDone;
+ h->pending = UNKNOWN;
+ }
+ if (h->after)
+ (*h->after)(h->afterArg, arb, h->stackPtr - h->stack, PR_FALSE);
+}
+
+SECStatus BER_ParseSome(BERParse *h, unsigned char *buf, int len)
+{
+ if (h->state == parseError) return PR_TRUE;
+
+ while (len) {
+ (*h->proc)(h, &buf, &len);
+ if (h->state == parseComplete) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ if (h->state == parseError) return PR_TRUE;
+ PORT_Assert(h->state != parseComplete);
+
+ if (h->state <= compositeDone) {
+ if (h->proc == ParseTag) {
+ PORT_Assert(h->state == tagDone);
+ h->proc = ParseLength;
+ h->state = notDone;
+ } else if (h->proc == ParseLength) {
+ SECArb *arb = &(h->stackPtr->arb);
+ PORT_Assert(h->state == lengthDone || h->state == compositeDone);
+
+ if (h->before)
+ (*h->before)(h->beforeArg, arb,
+ h->stackPtr - h->stack, PR_TRUE);
+
+ /*
+ * Check to see if this is the end of an indefinite
+ * length composite
+ */
+ if (h->state == compositeDone) {
+ SECArb *parent = h->stackPtr->parent;
+ PORT_Assert(parent);
+ PORT_Assert(parent->tag & DER_CONSTRUCTED);
+ if (parent->length != 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ /*
+ * NOTE: This does not check for an indefinite length
+ * composite being contained inside a definite length
+ * composite. It is not clear that is legal.
+ */
+ h->stackPtr--;
+ CreateArbNode(h);
+ } else {
+ h->stackPtr->pos = h->pos;
+
+
+ if (arb->tag & DER_CONSTRUCTED) {
+ SECArb *parent;
+ /*
+ * Make sure there is room on the stack before we
+ * stick anything else there.
+ */
+ PORT_Assert(h->stackPtr - h->stack < h->stackDepth);
+ if (h->stackPtr - h->stack == h->stackDepth - 1) {
+ int newDepth = h->stackDepth * 2;
+ h->stack = DS_ArenaGrow(h->mine, h->stack,
+ sizeof(ParseStackElem) * h->stackDepth,
+ sizeof(ParseStackElem) * newDepth);
+ h->stackPtr = h->stack + h->stackDepth + 1;
+ h->stackDepth = newDepth;
+ }
+ parent = &(h->stackPtr->arb);
+ h->stackPtr++;
+ h->stackPtr->parent = parent;
+ h->proc = ParseTag;
+ h->state = notDone;
+ h->pending = UNKNOWN;
+ } else {
+ if (arb->length < 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ arb->body.item.len = 0;
+ if (arb->length > 0 && h->keepLeaves) {
+ arb->body.item.data =
+ PORT_ArenaAlloc(h->his, arb->length);
+ } else {
+ arb->body.item.data = NULL;
+ }
+ h->proc = ParseLeaf;
+ h->state = notDone;
+ h->pending = arb->length;
+ }
+ }
+ } else {
+ ParseStackElem *parent;
+ PORT_Assert(h->state = leafDone);
+ PORT_Assert(h->proc == ParseLeaf);
+
+ for (;;) {
+ CreateArbNode(h);
+ if (h->stackPtr == h->stack)
+ break;
+ parent = (h->stackPtr - 1);
+ PORT_Assert(parent->arb.tag & DER_CONSTRUCTED);
+ if (parent->arb.length == 0) /* need explicit end */
+ break;
+ if (parent->pos + parent->arb.length > h->pos)
+ break;
+ if (parent->pos + parent->arb.length < h->pos) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ h->stackPtr = parent;
+ }
+ }
+
+ }
+ }
+ return PR_FALSE;
+}
+BERParse *BER_ParseInit(PRArenaPool *arena, PRBool derOnly)
+{
+ BERParse *h;
+ PRArenaPool *temp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (temp == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
+ }
+ h = PORT_ArenaAlloc(temp, sizeof(BERParse));
+ if (h == NULL) {
+ PORT_FreeArena(temp, PR_FALSE);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
+ }
+ h->his = arena;
+ h->mine = temp;
+ h->proc = ParseTag;
+ h->stackDepth = 20;
+ h->stack = PORT_ArenaZAlloc(h->mine,
+ sizeof(ParseStackElem) * h->stackDepth);
+ h->stackPtr = h->stack;
+ h->state = notDone;
+ h->pos = 0;
+ h->keepLeaves = PR_TRUE;
+ h->before = NULL;
+ h->after = NULL;
+ h->filter = NULL;
+ h->derOnly = derOnly;
+ return h;
+}
+
+SECArb *BER_ParseFini(BERParse *h)
+{
+ PRArenaPool *myArena = h->mine;
+ SECArb *arb;
+
+ if (h->state != parseComplete) {
+ arb = NULL;
+ } else {
+ arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
+ *arb = h->stackPtr->arb;
+ }
+
+ PORT_FreeArena(myArena, PR_FALSE);
+
+ return arb;
+}
+
+
+void BER_SetFilter(BERParse *h, BERFilterProc proc, void *instance)
+{
+ h->filter = proc;
+ h->filterArg = instance;
+}
+
+void BER_SetLeafStorage(BERParse *h, PRBool keep)
+{
+ h->keepLeaves = keep;
+}
+
+void BER_SetNotifyProc(BERParse *h, BERNotifyProc proc, void *instance,
+ PRBool beforeData)
+{
+ if (beforeData) {
+ h->before = proc;
+ h->beforeArg = instance;
+ } else {
+ h->after = proc;
+ h->afterArg = instance;
+ }
+}
+
+
+
diff --git a/security/nss/cmd/lib/config.mk b/security/nss/cmd/lib/config.mk
new file mode 100644
index 000000000..0a00dc61e
--- /dev/null
+++ b/security/nss/cmd/lib/config.mk
@@ -0,0 +1,43 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+TARGETS = $(LIBRARY)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+PROGRAM =
+
diff --git a/security/nss/cmd/lib/derprint.c b/security/nss/cmd/lib/derprint.c
new file mode 100644
index 000000000..7f699dec4
--- /dev/null
+++ b/security/nss/cmd/lib/derprint.c
@@ -0,0 +1,619 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secutil.h"
+#include "secoid.h"
+
+#ifdef __sun
+extern int fprintf(FILE *strm, const char *format, .../* args */);
+extern int fflush(FILE *stream);
+#endif
+
+#define RIGHT_MARGIN 24
+/*#define RAW_BYTES 1 */
+
+static int prettyColumn = 0;
+
+static int
+getInteger256(unsigned char *data, unsigned int nb)
+{
+ int val;
+
+ switch (nb) {
+ case 1:
+ val = data[0];
+ break;
+ case 2:
+ val = (data[0] << 8) | data[1];
+ break;
+ case 3:
+ val = (data[0] << 16) | (data[1] << 8) | data[2];
+ break;
+ case 4:
+ val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ return val;
+}
+
+static int
+prettyNewline(FILE *out)
+{
+ int rv;
+
+ if (prettyColumn != -1) {
+ rv = fprintf(out, "\n");
+ prettyColumn = -1;
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+ return 0;
+}
+
+static int
+prettyIndent(FILE *out, unsigned level)
+{
+ unsigned int i;
+ int rv;
+
+ if (prettyColumn == -1) {
+ prettyColumn = level;
+ for (i = 0; i < level; i++) {
+ rv = fprintf(out, " ");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintByte(FILE *out, unsigned char item, unsigned int level)
+{
+ int rv;
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ rv = fprintf(out, "%02x ", item);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ prettyColumn++;
+ if (prettyColumn >= RIGHT_MARGIN) {
+ return prettyNewline(out);
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintLeaf(FILE *out, unsigned char *data,
+ unsigned int len, unsigned int lv)
+{
+ unsigned int i;
+ int rv;
+
+ for (i = 0; i < len; i++) {
+ rv = prettyPrintByte(out, *data++, lv);
+ if (rv < 0)
+ return rv;
+ }
+ return prettyNewline(out);
+}
+
+static int
+prettyPrintStringStart(FILE *out, unsigned char *str,
+ unsigned int len, unsigned int level)
+{
+#define BUF_SIZE 100
+ unsigned char buf[BUF_SIZE];
+ int rv;
+
+ if (len >= BUF_SIZE)
+ len = BUF_SIZE - 1;
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ memcpy(buf, str, len);
+ buf[len] = '\000';
+
+ rv = fprintf(out, "\"%s\"", buf);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ return 0;
+#undef BUF_SIZE
+}
+
+static int
+prettyPrintString(FILE *out, unsigned char *str,
+ unsigned int len, unsigned int level, PRBool raw)
+{
+ int rv;
+
+ rv = prettyPrintStringStart(out, str, len, level);
+ if (rv < 0)
+ return rv;
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ if (raw) {
+ rv = prettyPrintLeaf(out, str, len, level);
+ if (rv < 0)
+ return rv;
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintTime(FILE *out, unsigned char *str,
+ unsigned int len, unsigned int level, PRBool raw, PRBool utc)
+{
+ SECItem time_item;
+ int rv;
+
+ rv = prettyPrintStringStart(out, str, len, level);
+ if (rv < 0)
+ return rv;
+
+ time_item.data = str;
+ time_item.len = len;
+
+ rv = fprintf(out, " (");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ if (utc)
+ SECU_PrintUTCTime(out, &time_item, NULL, 0);
+ else
+ SECU_PrintGeneralizedTime(out, &time_item, NULL, 0);
+
+ rv = fprintf(out, ")");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ if (raw) {
+ rv = prettyPrintLeaf(out, str, len, level);
+ if (rv < 0)
+ return rv;
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintObjectID(FILE *out, unsigned char *data,
+ unsigned int len, unsigned int level, PRBool raw)
+{
+ SECOidData *oiddata;
+ SECItem oiditem;
+ unsigned int i;
+ unsigned long val;
+ int rv;
+
+
+ /*
+ * First print the Object Id in numeric format
+ */
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ val = data[0];
+ i = val % 40;
+ val = val / 40;
+ rv = fprintf(out, "%lu %u ", val, i);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ val = 0;
+ for (i = 1; i < len; ++i) {
+ unsigned long j;
+
+ j = data[i];
+ val = (val << 7) | (j & 0x7f);
+ if (j & 0x80)
+ continue;
+ rv = fprintf(out, "%lu ", val);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ val = 0;
+ }
+
+ /*
+ * Now try to look it up and print a symbolic version.
+ */
+ oiditem.data = data;
+ oiditem.len = len;
+ oiddata = SECOID_FindOID(&oiditem);
+ if (oiddata != NULL) {
+ i = PORT_Strlen(oiddata->desc);
+ if ((prettyColumn + 1 + (i / 3)) > RIGHT_MARGIN) {
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+ }
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ rv = fprintf(out, "(%s)", oiddata->desc);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+
+ /*
+ * Finally, on a new line, print the raw bytes (if requested).
+ */
+ if (raw) {
+ rv = prettyNewline(out);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ for (i = 0; i < len; i++) {
+ rv = prettyPrintByte(out, *data++, level);
+ if (rv < 0)
+ return rv;
+ }
+ }
+
+ return prettyNewline(out);
+}
+
+static char *prettyTagType [32] = {
+ "End of Contents",
+ "Boolean",
+ "Integer",
+ "Bit String",
+ "Octet String",
+ "NULL",
+ "Object Identifier",
+ "0x07",
+ "0x08",
+ "0x09",
+ "Enumerated",
+ "0x0B",
+ "UTF8 String",
+ "0x0D",
+ "0x0E",
+ "0x0F",
+ "Sequence",
+ "Set",
+ "0x12",
+ "Printable String",
+ "T61 String",
+ "0x15",
+ "IA5 String",
+ "UTC Time",
+ "Generalized Time",
+ "0x19",
+ "Visible String",
+ "0x1B",
+ "Universal String",
+ "0x1D",
+ "BMP String",
+ "High-Tag-Number"
+};
+
+static int
+prettyPrintTag(FILE *out, unsigned char *src, unsigned char *end,
+ unsigned char *codep, unsigned int level, PRBool raw)
+{
+ int rv;
+ unsigned char code, tagnum;
+
+ if (src >= end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ code = *src;
+ tagnum = code & SEC_ASN1_TAGNUM_MASK;
+
+ /*
+ * NOTE: This code does not (yet) handle the high-tag-number form!
+ */
+ if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ if (raw)
+ rv = prettyPrintByte(out, code, level);
+ else
+ rv = prettyIndent(out, level);
+
+ if (rv < 0)
+ return rv;
+
+ if (code & SEC_ASN1_CONSTRUCTED) {
+ rv = fprintf(out, "C-");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+
+ switch (code & SEC_ASN1_CLASS_MASK) {
+ case SEC_ASN1_UNIVERSAL:
+ rv = fprintf(out, "%s ", prettyTagType[tagnum]);
+ break;
+ case SEC_ASN1_APPLICATION:
+ rv = fprintf(out, "Application: %d ", tagnum);
+ break;
+ case SEC_ASN1_CONTEXT_SPECIFIC:
+ rv = fprintf(out, "[%d] ", tagnum);
+ break;
+ case SEC_ASN1_PRIVATE:
+ rv = fprintf(out, "Private: %d ", tagnum);
+ break;
+ }
+
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ *codep = code;
+
+ return 1;
+}
+
+static int
+prettyPrintLength(FILE *out, unsigned char *data, unsigned char *end,
+ int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw)
+{
+ unsigned char lbyte;
+ int lenLen;
+ int rv;
+
+ if (data >= end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ rv = fprintf(out, " ");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ *indefinitep = PR_FALSE;
+
+ lbyte = *data++;
+ if (lbyte >= 0x80) {
+ /* Multibyte length */
+ unsigned nb = (unsigned) (lbyte & 0x7f);
+ if (nb > 4) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ if (nb > 0) {
+ int il;
+
+ if ((data + nb) > end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ il = getInteger256(data, nb);
+ if (il < 0) return -1;
+ *lenp = (unsigned) il;
+ } else {
+ *lenp = 0;
+ *indefinitep = PR_TRUE;
+ }
+ lenLen = nb + 1;
+ if (raw) {
+ int i;
+
+ rv = prettyPrintByte(out, lbyte, lv);
+ if (rv < 0)
+ return rv;
+ for (i = 0; i < nb; i++) {
+ rv = prettyPrintByte(out, data[i], lv);
+ if (rv < 0)
+ return rv;
+ }
+ }
+ } else {
+ *lenp = lbyte;
+ lenLen = 1;
+ if (raw) {
+ rv = prettyPrintByte(out, lbyte, lv);
+ if (rv < 0)
+ return rv;
+ }
+ }
+ if (*indefinitep)
+ rv = fprintf(out, "(indefinite)\n");
+ else
+ rv = fprintf(out, "(%d)\n", *lenp);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ prettyColumn = -1;
+ return lenLen;
+}
+
+static int
+prettyPrintItem(FILE *out, unsigned char *data, unsigned char *end,
+ unsigned int lv, PRBool raw)
+{
+ int slen;
+ int lenLen;
+ unsigned char *orig = data;
+ int rv;
+
+ while (data < end) {
+ unsigned char code;
+ PRBool indefinite;
+
+ slen = prettyPrintTag(out, data, end, &code, lv, raw);
+ if (slen < 0)
+ return slen;
+ data += slen;
+
+ lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw);
+ if (lenLen < 0)
+ return lenLen;
+ data += lenLen;
+
+ /*
+ * Just quit now if slen more bytes puts us off the end.
+ */
+ if ((data + slen) > end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ if (code & SEC_ASN1_CONSTRUCTED) {
+ if (slen > 0 || indefinite) {
+ slen = prettyPrintItem(out, data,
+ slen == 0 ? end : data + slen,
+ lv+1, raw);
+ if (slen < 0)
+ return slen;
+ data += slen;
+ }
+ } else if (code == 0) {
+ if (slen != 0 || lenLen != 1) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ break;
+ } else {
+ switch (code) {
+ case SEC_ASN1_PRINTABLE_STRING:
+ case SEC_ASN1_IA5_STRING:
+ case SEC_ASN1_VISIBLE_STRING:
+ rv = prettyPrintString(out, data, slen, lv+1, raw);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_UTC_TIME:
+ rv = prettyPrintTime(out, data, slen, lv+1, raw, PR_TRUE);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_GENERALIZED_TIME:
+ rv = prettyPrintTime(out, data, slen, lv+1, raw, PR_FALSE);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_OBJECT_ID:
+ rv = prettyPrintObjectID(out, data, slen, lv+1, raw);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_BOOLEAN: /* could do nicer job */
+ case SEC_ASN1_INTEGER: /* could do nicer job */
+ case SEC_ASN1_BIT_STRING: /* could do nicer job */
+ case SEC_ASN1_OCTET_STRING:
+ case SEC_ASN1_NULL:
+ case SEC_ASN1_ENUMERATED: /* could do nicer job, as INTEGER */
+ case SEC_ASN1_UTF8_STRING:
+ case SEC_ASN1_T61_STRING: /* print as printable string? */
+ case SEC_ASN1_UNIVERSAL_STRING:
+ case SEC_ASN1_BMP_STRING:
+ default:
+ rv = prettyPrintLeaf(out, data, slen, lv+1);
+ if (rv < 0)
+ return rv;
+ break;
+ }
+ data += slen;
+ }
+ }
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ return data - orig;
+}
+
+SECStatus
+DER_PrettyPrint(FILE *out, SECItem *it, PRBool raw)
+{
+ int rv;
+
+ prettyColumn = -1;
+
+ rv = prettyPrintItem(out, it->data, it->data + it->len, 0, raw);
+ if (rv < 0)
+ return SECFailure;
+ return SECSuccess;
+}
diff --git a/security/nss/cmd/lib/dongle.c b/security/nss/cmd/lib/dongle.c
new file mode 100644
index 000000000..1c819ee51
--- /dev/null
+++ b/security/nss/cmd/lib/dongle.c
@@ -0,0 +1,249 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secutil.h"
+#include "sechash.h"
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#endif
+#ifdef XP_WIN
+#include <windows.h>
+#include <winsock.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#ifdef XP_MAC
+#include <unistd.h>
+#endif
+
+#ifdef XP_UNIX
+#include "prnetdb.h"
+#else
+#define PRHostEnt struct hostent
+#define PR_NETDB_BUF_SIZE 5
+#endif
+
+static RC4Context *
+sec_MakeDongleKey(void)
+{
+ RC4Context *rc4;
+ char hostname[64];
+ PRHostEnt hpbuf, *hent;
+ char dbbuf[PR_NETDB_BUF_SIZE];
+ int ipaddr;
+ struct stat s;
+ int found = 1; /* Whether /vmunix, etc. found */
+ unsigned char *buf, *totalbuf;
+ MD5Context *md5 = 0;
+ unsigned char digest[16];
+ unsigned int digestLen;
+
+ /* NOTE: Fix MAC and WIN to stat something comparable to kernel on UNIX */
+#ifdef XP_MAC
+ return NULL;
+#elif defined(XP_WIN)
+ return NULL;
+#endif
+
+ /* gather system data */
+ if( gethostname( hostname, 64 ) < 0 ) {
+ return(NULL);
+ }
+
+#ifdef XP_UNIX
+#ifndef NSPR20
+ hent = PR_gethostbyname(hostname, &hpbuf, dbbuf, sizeof(dbbuf), 0);
+#else
+ if (PR_GetHostByName(hostname, dbbuf, sizeof(dbbuf), &hpbuf) == PR_SUCCESS)
+ hent = &hpbuf;
+ else
+ hent = NULL;
+#endif
+#else
+ hent = gethostbyname(hostname);
+#endif
+ if (hent == NULL) {
+ return(NULL);
+ }
+
+ ipaddr = htonl(((struct in_addr *)hent->h_addr)->s_addr);
+
+ /*
+ ** /unix IRIX & AIX & SCO
+ ** /vmunix SunOS & OSF
+ ** /kernel/unix Solaris
+ ** /vmlinuz Linux
+ ** /hp-ux HP-UX
+ ** /bsd BSD
+ */
+ if ( (stat("/unix", &s) == -1 ) && (stat("/vmunix", &s) == -1) &&
+ (stat("/bsd", &s) == -1) && (stat("kernel/unix", &s)== -1) &&
+ (stat("/hp-ux", &s) == -1) && (stat("/vmlinuz", &s) == -1) ) {
+ found = 0;
+ }
+
+ buf = totalbuf = (unsigned char *)
+ XP_CALLOC(1, 1000 + sizeof(ipaddr) + sizeof(s) + PORT_Strlen(hostname));
+
+ if ( buf == 0 ) {
+ return(NULL);
+ }
+
+ PORT_Memcpy(buf, hostname, PORT_Strlen(hostname));
+ buf += PORT_Strlen(hostname);
+
+ PORT_Memcpy(buf, &ipaddr, sizeof(ipaddr));
+ buf += sizeof(ipaddr);
+
+ if (found) {
+ PORT_Memcpy(buf, &s.st_mode, sizeof(s.st_mode));
+ buf += sizeof(s.st_mode);
+
+ PORT_Memcpy(buf, &s.st_ino, sizeof(s.st_ino));
+ buf += sizeof(s.st_ino);
+
+ PORT_Memcpy(buf, &s.st_dev, sizeof(s.st_dev));
+ buf += sizeof(s.st_dev);
+
+ PORT_Memcpy(buf, &s.st_mtime, sizeof(s.st_mtime));
+ buf += sizeof(s.st_mtime);
+ }
+
+ /* Digest the system info using MD5 */
+ md5 = MD5_NewContext();
+ if (md5 == NULL) {
+ return (NULL);
+ }
+
+ MD5_Begin(md5);
+ MD5_Update(md5, totalbuf, PORT_Strlen((char *)totalbuf));
+ MD5_End(md5, digest, &digestLen, MD5_LENGTH);
+
+ /* Make an RC4 key using the digest */
+ rc4 = RC4_CreateContext(digest, digestLen);
+
+ /* Zero out information */
+ MD5_DestroyContext(md5, PR_TRUE);
+ PORT_Memset(digest, 0 , sizeof(digest));
+
+
+ return(rc4);
+}
+
+extern unsigned char *
+SEC_ReadDongleFile(int fd)
+{
+ RC4Context *rc4;
+ struct stat s;
+ unsigned char *inbuf, *pw;
+ int nb;
+ unsigned int pwlen, inlen;
+ SECStatus rv;
+
+ rc4 = sec_MakeDongleKey();
+ if (rc4 == NULL) {
+ return(0);
+ }
+
+ /* get size of file */
+ if ( fstat(fd, &s) < 0 ) {
+ return(0);
+ }
+
+ inlen = s.st_size;
+
+ inbuf = (unsigned char *) PORT_Alloc(inlen);
+ if (!inbuf) {
+ return(0);
+ }
+
+ nb = read(fd, (char *)inbuf, inlen);
+ if (nb != inlen) {
+ return(0);
+ }
+
+ pw = (unsigned char *) PORT_Alloc(inlen);
+ if (pw == 0) {
+ return(0);
+ }
+
+ rv = RC4_Decrypt(rc4, pw, &pwlen, inlen, inbuf, inlen);
+ if (rv) {
+ return(0);
+ }
+
+ PORT_Free(inbuf);
+
+ return(pw);
+}
+
+extern SECStatus
+SEC_WriteDongleFile(int fd, unsigned char *pw)
+{
+ RC4Context *rc4;
+ unsigned char *outbuf;
+ unsigned int outlen;
+ SECStatus rv;
+ int nb;
+
+ rc4 = sec_MakeDongleKey();
+ if (rc4 == NULL) {
+ return(SECFailure);
+ }
+
+ outbuf = (unsigned char *) PORT_Alloc(PORT_Strlen((char *)pw) + 1);
+ if (!outbuf) {
+ return(SECFailure);
+ }
+
+ rv = RC4_Encrypt(rc4, outbuf, &outlen, PORT_Strlen((char *)pw), pw,
+ PORT_Strlen((char *)pw));
+ if (rv) {
+ return(SECFailure);
+ }
+
+ RC4_DestroyContext(rc4, PR_TRUE);
+
+ nb = write(fd, (char *)outbuf, outlen);
+ if (nb != outlen) {
+ return(SECFailure);
+ }
+
+ PORT_Free(outbuf);
+
+ return(SECSuccess);
+}
+
diff --git a/security/nss/cmd/lib/fe_util.c b/security/nss/cmd/lib/fe_util.c
new file mode 100644
index 000000000..646277e35
--- /dev/null
+++ b/security/nss/cmd/lib/fe_util.c
@@ -0,0 +1,40 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secpkcs7.h"
+
+void
+fe_GetProgramDirectory(char *path, int len)
+{
+ PORT_Strcpy( path, ".");
+}
+
diff --git a/security/nss/cmd/lib/ffs.c b/security/nss/cmd/lib/ffs.c
new file mode 100644
index 000000000..3fce2c7c2
--- /dev/null
+++ b/security/nss/cmd/lib/ffs.c
@@ -0,0 +1,48 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#ifdef XP_PC
+
+int ffs( unsigned int i)
+{
+ int rv = 1;
+
+ if (!i) return 0;
+
+ while (!(i & 1)) {
+ i >>= 1;
+ ++rv;
+ }
+
+ return rv;
+}
+#endif
diff --git a/security/nss/cmd/lib/filestub.c b/security/nss/cmd/lib/filestub.c
new file mode 100644
index 000000000..368b7284d
--- /dev/null
+++ b/security/nss/cmd/lib/filestub.c
@@ -0,0 +1,1118 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#define CMD_STUB 1 /* this is just a stub for security/cmd/* */
+#define MOZ_LITE 1 /* don't need that other stuff, either */
+
+#if 0
+#include "stdafx.h"
+#include "dialog.h"
+#include "mainfrm.h"
+#include "custom.h"
+#include "shcut.h"
+#include "edt.h"
+#include "prmon.h"
+#include "fegui.h"
+#include "prefapi.h"
+#include <io.h>
+#include "secrng.h"
+#include "mailass.h"
+#include "ipframe.h"
+#include "mnprefs.h"
+
+#else
+
+#include <xp_core.h>
+#include <xp_file.h>
+#include <xp_mcom.h>
+
+#define ASSERT assert
+#endif
+
+#ifdef XP_MAC
+#include "prpriv.h" /* For PR_NewNamedMonitor */
+#else
+#include "private/prpriv.h"
+#endif
+
+#ifdef XP_WIN
+
+#ifndef _AFXDLL
+/* MSVC Debugging new...goes to regular new in release mode */
+#define new DEBUG_NEW
+#endif
+
+#ifdef __BORLANDC__
+ #define _lseek lseek
+#endif
+
+#define WIDTHBYTES(i) ((i + 31) / 32 * 4)
+#define MAXREAD 32767
+
+MODULE_PRIVATE char * XP_CacheFileName();
+
+#define MAXSTRINGLEN 8192
+
+#ifndef CMD_STUB
+
+/* Return a string the same as the In string
+** but with all of the \n's replaced with \r\n's
+*/
+MODULE_PRIVATE char *
+FE_Windowsify(const char * In)
+{
+ char *Out;
+ char *o, *i;
+ int32 len;
+
+ if(!In)
+ return NULL;
+
+ /* if every character is a \n then new string is twice as long */
+ len = (int32) XP_STRLEN(In) * 2 + 1;
+ Out = (char *) XP_ALLOC(len);
+ if(!Out)
+ return NULL;
+
+ /* Move the characters over one by one. If the current character is */
+ /* a \n replace add a \r before moving the \n over */
+ for(i = (char *) In, o = Out; i && *i; *o++ = *i++)
+ if(*i == '\n')
+ *o++ = '\r';
+
+ /* Make sure our new string is NULL terminated */
+ *o = '\0';
+ return(Out);
+}
+
+
+/* Return some adjusted out full path on the mac. */
+/* For windows, we just return what was passed in. */
+/* We must provide it in a seperate buffer, otherwise they might change */
+/* the original and change also what they believe to be saved. */
+char *
+WH_FilePlatformName(const char *pName)
+{
+
+ if(pName) {
+ return XP_STRDUP(pName);
+ }
+
+ return NULL;
+}
+
+
+char *
+FE_GetProgramDirectory(char *buffer, int length)
+{
+ ::GetModuleFileName(theApp.m_hInstance, buffer, length);
+
+ /* Find the trailing slash. */
+ char *pSlash = ::strrchr(buffer, '\\');
+ if(pSlash) {
+ *(pSlash+1) = '\0';
+ } else {
+ buffer[0] = '\0';
+ }
+ return (buffer);
+}
+
+
+char*
+XP_TempDirName(void)
+{
+ char *tmp = theApp.m_pTempDir;
+ if (!tmp)
+ return XP_STRDUP(".");
+ return XP_STRDUP(tmp);
+}
+
+/* Windows _tempnam() lets the TMP environment variable override things sent
+** in so it look like we're going to have to make a temp name by hand.
+
+** The user should *NOT* free the returned string.
+** It is stored in static space
+** and so is not valid across multiple calls to this function.
+
+** The names generated look like
+** c:\netscape\cache\m0.moz
+** c:\netscape\cache\m1.moz
+** up to...
+** c:\netscape\cache\m9999999.moz
+** after that if fails
+** */
+PUBLIC char *
+xp_TempFileName(int type, const char * request_prefix, const char * extension,
+ char* file_buf)
+{
+ const char * directory = NULL;
+ char * ext = NULL; /* file extension if any */
+ char * prefix = NULL; /* file prefix if any */
+
+
+ XP_StatStruct statinfo;
+ int status;
+
+ /* */
+ /* based on the type of request determine what directory we should be */
+ /* looking into */
+ /* */
+ switch(type) {
+ case xpCache:
+ directory = theApp.m_pCacheDir;
+ ext = ".MOZ";
+ prefix = CACHE_PREFIX;
+ break;
+#ifndef MOZ_LITE
+ case xpSNewsRC:
+ case xpNewsRC:
+ case xpNewsgroups:
+ case xpSNewsgroups:
+ case xpTemporaryNewsRC:
+ directory = g_MsgPrefs.m_csNewsDir;
+ ext = (char *)extension;
+ prefix = (char *)request_prefix;
+ break;
+ case xpMailFolderSummary:
+ case xpMailFolder:
+ directory = g_MsgPrefs.m_csMailDir;
+ ext = (char *)extension;
+ prefix = (char *)request_prefix;
+ break;
+ case xpAddrBook:
+ /*changed to support multi-profile */
+ /*directory = theApp.m_pInstallDir->GetCharValue(); */
+ directory = (const char *)theApp.m_UserDirectory;
+ if ((request_prefix == 0) || (XP_STRLEN (request_prefix) == 0))
+ prefix = "abook";
+ ext = ".nab";
+ break;
+#endif /* MOZ_LITE */
+ case xpCacheFAT:
+ directory = theApp.m_pCacheDir;
+ prefix = "fat";
+ ext = "db";
+ break;
+ case xpJPEGFile:
+ directory = theApp.m_pTempDir;
+ ext = ".jpg";
+ prefix = (char *)request_prefix;
+ break;
+ case xpPKCS12File:
+ directory = theApp.m_pTempDir;
+ ext = ".p12";
+ prefix = (char *)request_prefix;
+ break;
+ case xpTemporary:
+ default:
+ directory = theApp.m_pTempDir;
+ ext = (char *)extension;
+ prefix = (char *)request_prefix;
+ break;
+ }
+
+ if(!directory)
+ return(NULL);
+
+ if(!prefix)
+ prefix = "X";
+
+ if(!ext)
+ ext = ".TMP";
+
+ /* We need to base our temporary file names on time, and not on sequential */
+ /* addition because of the cache not being updated when the user */
+ /* crashes and files that have been deleted are over written with */
+ /* other files; bad data. */
+ /* The 52 valid DOS file name characters are */
+ /* 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_^$~!#%&-{}@`'() */
+ /* We will only be using the first 32 of the choices. */
+ /* */
+ /* Time name format will be M+++++++.MOZ */
+ /* Where M is the single letter prefix (can be longer....) */
+ /* Where +++++++ is the 7 character time representation (a full 8.3 */
+ /* file name will be made). */
+ /* Where .MOZ is the file extension to be used. */
+ /* */
+ /* In the event that the time requested is the same time as the last call */
+ /* to this function, then the current time is incremented by one, */
+ /* as is the last time called to facilitate unique file names. */
+ /* In the event that the invented file name already exists (can't */
+ /* really happen statistically unless the clock is messed up or we */
+ /* manually incremented the time), then the times are incremented */
+ /* until an open name can be found. */
+ /* */
+ /* time_t (the time) has 32 bits, or 4,294,967,296 combinations. */
+ /* We will map the 32 bits into the 7 possible characters as follows: */
+ /* Starting with the lsb, sets of 5 bits (32 values) will be mapped */
+ /* over to the appropriate file name character, and then */
+ /* incremented to an approprate file name character. */
+ /* The left over 2 bits will be mapped into the seventh file name */
+ /* character. */
+ /* */
+
+ int i_letter, i_timechars, i_numtries = 0;
+ char ca_time[8];
+ time_t this_call = (time_t)0;
+
+ /* We have to base the length of our time string on the length */
+ /* of the incoming prefix.... */
+ /* */
+ i_timechars = 8 - strlen(prefix);
+
+ /* Infinite loop until the conditions are satisfied. */
+ /* There is no danger, unless every possible file name is used. */
+ /* */
+ while(1) {
+ /* We used to use the time to generate this. */
+ /* Now, we use some crypto to avoid bug #47027 */
+ RNG_GenerateGlobalRandomBytes((void *)&this_call, sizeof(this_call));
+
+ /* Convert the time into a 7 character string. */
+ /* Strip only the signifigant 5 bits. */
+ /* We'll want to reverse the string to make it look coherent */
+ /* in a directory of file names. */
+ /* */
+ for(i_letter = 0; i_letter < i_timechars; i_letter++) {
+ ca_time[i_letter] = (char)((this_call >> (i_letter * 5)) & 0x1F);
+
+ /* Convert any numbers to their equivalent ascii code */
+ /* */
+ if(ca_time[i_letter] <= 9) {
+ ca_time[i_letter] += '0';
+ }
+ /* Convert the character to it's equivalent ascii code */
+ /* */
+ else {
+ ca_time[i_letter] += 'A' - 10;
+ }
+ }
+
+ /* End the created time string. */
+ /* */
+ ca_time[i_letter] = '\0';
+
+ /* Reverse the time string. */
+ /* */
+ _strrev(ca_time);
+
+ /* Create the fully qualified path and file name. */
+ /* */
+ sprintf(file_buf, "%s\\%s%s%s", directory, prefix, ca_time, ext);
+
+ /* Determine if the file exists, and mark that we've tried yet */
+ /* another file name (mark to be used later). */
+ /* */
+ /* Use the system call instead of XP_Stat since we already */
+ /* know the name and we don't want recursion */
+ /* */
+ status = _stat(file_buf, &statinfo);
+ i_numtries++;
+
+ /* If it does not exists, we are successful, return the name. */
+ /* */
+ if(status == -1) {
+ /* don't generate a directory as part of the cache temp names.
+ * When the cache file name is passed into the other XP_File
+ * functions we will append the cache directory to the name
+ * to get the complete path.
+ * This will allow the cache to be moved around
+ * and for netscape to be used to generate external cache FAT's.
+ */
+ if(type == xpCache )
+ sprintf(file_buf, "%s%s%s", prefix, ca_time, ext);
+
+ TRACE("Temp file name is %s\n", file_buf);
+ return(file_buf);
+ }
+
+ /* If there is no room for additional characters in the time, */
+ /* we'll have to return NULL here, or we go infinite. */
+ /* This is a one case scenario where the requested prefix is */
+ /* actually 8 letters long! */
+ /* Infinite loops could occur with a 7, 6, 5, etc character prefixes */
+ /* if available files are all eaten up (rare to impossible), in */
+ /* which case, we should check at some arbitrary frequency of */
+ /* tries before we give up instead of attempting to Vulcanize */
+ /* this code. Live long and prosper. */
+ /* */
+ if(i_timechars == 0) {
+ break;
+ } else if(i_numtries == 0x00FF) {
+ break;
+ }
+ }
+
+ /* Requested name is thought to be impossible to generate. */
+ /* */
+ TRACE("No more temp file names....\n");
+ return(NULL);
+
+}
+
+PUBLIC char *
+WH_TempFileName(int type, const char * request_prefix, const char * extension)
+{
+ static char file_buf[_MAX_PATH]; /* protected by _pr_TempName_lock */
+ char* result;
+
+ if (_pr_TempName_lock == NULL)
+ _pr_TempName_lock = PR_NewNamedMonitor("TempName-lock");
+ PR_EnterMonitor(_pr_TempName_lock);
+
+ result = XP_STRDUP(xp_TempFileName(type, request_prefix, extension, file_buf));
+ PR_ExitMonitor(_pr_TempName_lock);
+ return result;
+}
+
+#endif /* CMD_STUB */
+
+/* */
+/* Return a string that is equal to the NetName string but with the */
+/* cross-platform characters changed back into DOS characters */
+/* The caller is responsible for XP_FREE()ing the string */
+/* */
+MODULE_PRIVATE char *
+XP_NetToDosFileName(const char * NetName)
+{
+ char *p, *newName;
+ BOOL bChopSlash = FALSE;
+
+ if(!NetName)
+ return NULL;
+
+ /* If the name is only '/' or begins '//' keep the */
+ /* whole name else strip the leading '/' */
+
+ if(NetName[0] == '/')
+ bChopSlash = TRUE;
+
+ /* save just / as a path */
+ if(NetName[0] == '/' && NetName[1] == '\0')
+ bChopSlash = FALSE;
+
+ /* spanky Win9X path name */
+ if(NetName[0] == '/' && NetName[1] == '/')
+ bChopSlash = FALSE;
+
+ if(bChopSlash)
+ newName = XP_STRDUP(&(NetName[1]));
+ else
+ newName = XP_STRDUP(NetName);
+
+ if(!newName)
+ return NULL;
+
+ for(p = newName; *p; p++) {
+ switch(*p) {
+ case '|':
+ *p = ':';
+ break;
+ case '/':
+ *p = '\\';
+ break;
+ default:
+ break;
+ }
+ }
+
+ return(newName);
+
+}
+
+
+/* */
+/* Returns the absolute name of a file */
+/* */
+/* The result of this function can be used with the standard */
+/* open/fopen ansi file functions */
+/* */
+PUBLIC char *
+xp_FileName(const char * name, XP_FileType type, char* *myName)
+{
+ char * newName = NULL;
+ char * netLibName = NULL;
+ char * tempName = NULL;
+ char * prefStr = NULL;
+ BOOL bNeedToRegister = FALSE; /* == do we need to register a new */
+ /* newshost->file name mapping */
+ struct _stat sInfo;
+ int iDot;
+ int iColon;
+
+#ifndef CMD_STUB
+ CString csHostName;
+ CString csHost;
+ CString fileName;
+#endif
+
+ switch(type) {
+
+#ifndef CMD_STUB
+ case xpCacheFAT:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\fat.db", (const char *)theApp.m_pCacheDir);
+ break;
+ case xpExtCacheIndex:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\extcache.fat", (const char *)theApp.m_pCacheDir);
+ break;
+
+ case xpSARCacheIndex:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\archive.fat", theApp.m_pSARCacheDir);
+ break;
+
+ case xpHTTPCookie:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ /*sprintf(newName, "%s\\cookies.txt", theApp.m_pInstallDir->GetCharValue()); */
+ /* changed to support multi-profile */
+ sprintf(newName, "%s\\cookies.txt", (const char *)theApp.m_UserDirectory);
+ break;
+#ifndef MOZ_LITE
+ case xpSNewsRC:
+ case xpNewsRC:
+ /* see if we are asking about the default news host */
+ /* else look up in netlib */
+ if ( !name || !strlen(name) )
+ name = g_MsgPrefs.m_csNewsHost;
+
+ netLibName = NET_MapNewsrcHostToFilename((char *)name,
+ (type == xpSNewsRC),
+ FALSE);
+
+ /* if we found something in our map just skip the rest of this */
+ if(netLibName && *netLibName) {
+ newName = XP_STRDUP(netLibName);
+ break;
+ }
+
+ /* whatever name we eventually end up with we will need to register it */
+ /* before we leave the function */
+ bNeedToRegister = TRUE;
+
+ /* If we are on the default host see if there is a newsrc file in the */
+ /* news directory. If so, that is what we want */
+ if(!stricmp(name, g_MsgPrefs.m_csNewsHost)) {
+ csHostName = g_MsgPrefs.m_csNewsDir;
+ csHostName += "\\newsrc";
+ if(_stat((const char *) csHostName, &sInfo) == 0) {
+ newName = XP_STRDUP((const char *) csHostName);
+ break;
+ }
+ }
+
+ /* See if we are going to be able to build a file name based */
+ /* on the hostname */
+ csHostName = g_MsgPrefs.m_csNewsDir;
+ csHostName += '\\';
+
+ /* build up '<hostname>.rc' so we can tell how long its going to be */
+ /* we will use that as the default name to try */
+ if(type == xpSNewsRC)
+ csHost += 's';
+ csHost += name;
+
+ /* if we have a news host news.foo.com we just want to use the "news" */
+ /* part */
+ iDot = csHost.Find('.');
+ if(iDot != -1)
+ csHost = csHost.Left(iDot);
+
+#ifdef XP_WIN16
+ if(csHost.GetLength() > 8)
+ csHost = csHost.Left(8);
+#endif
+
+ iColon = csHost.Find(':');
+ if (iColon != -1) {
+ /* Windows file system seems to do horrid things if you have */
+ /* a filename with a colon in it. */
+ csHost = csHost.Left(iColon);
+ }
+
+ csHost += ".rc";
+
+ /* csHost is now of the form <hostname>.rc and is in 8.3 format */
+ /* if we are on a Win16 box */
+
+ csHostName += csHost;
+
+ /* looks like a file with that name already exists -- panic */
+ if(_stat((const char *) csHostName, &sInfo) != -1) {
+
+ char host[5];
+
+ /* else generate a new file in news directory */
+ strncpy(host, name, 4);
+ host[4] = '\0';
+
+ newName = WH_TempFileName(type, host, ".rc");
+ if(!newName)
+ return(NULL);
+
+ } else {
+
+ newName = XP_STRDUP((const char *) csHostName);
+
+ }
+
+ break;
+ case xpNewsrcFileMap:
+ /* return name of FAT file in news directory */
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\fat", (const char *)g_MsgPrefs.m_csNewsDir);
+ break;
+ case xpNewsgroups:
+ case xpSNewsgroups:
+ /* look up in netlib */
+ if ( !name || !strlen(name) )
+ name = g_MsgPrefs.m_csNewsHost;
+
+ netLibName = NET_MapNewsrcHostToFilename((char *)name,
+ (type == xpSNewsgroups),
+ TRUE);
+
+ if(!netLibName) {
+
+ csHostName = g_MsgPrefs.m_csNewsDir;
+ csHostName += '\\';
+
+ if(type == xpSNewsgroups)
+ csHost += 's';
+ csHost += name;
+
+ /* see if we can just use "<hostname>.rcg" */
+ /* it might be news.foo.com so just take "news" */
+ int iDot = csHost.Find('.');
+ if(iDot != -1)
+ csHost = csHost.Left(iDot);
+
+#ifdef XP_WIN16
+ if(csHost.GetLength() > 8)
+ csHost = csHost.Left(8);
+#endif
+
+ iColon = csHost.Find(':');
+ if (iColon != -1) {
+ /* Windows file system seems to do horrid things if you have */
+ /* a filename with a colon in it. */
+ csHost = csHost.Left(iColon);
+ }
+
+ csHost += ".rcg";
+
+ /* csHost is now of the form <hostname>.rcg */
+
+ csHostName += csHost;
+
+ /* looks like a file with that name already exists -- panic */
+ if(_stat((const char *) csHostName, &sInfo) != -1) {
+
+ char host[5];
+
+ /* else generate a new file in news directory */
+ strncpy(host, name, 4);
+ host[4] = '\0';
+
+ newName = WH_TempFileName(type, host, ".rcg");
+ if(!newName)
+ return(NULL);
+
+ } else {
+
+ newName = XP_STRDUP((const char *) csHostName);
+
+ }
+
+ if ( !name || !strlen(name))
+ NET_RegisterNewsrcFile(newName,(char *)(const char *)g_MsgPrefs.m_csNewsHost,
+ (type == xpSNewsgroups), TRUE );
+ else
+ NET_RegisterNewsrcFile(newName,(char*)name,(type == xpSNewsgroups), TRUE );
+
+ } else {
+
+ newName = XP_STRDUP(netLibName);
+
+ }
+ break;
+ case xpMimeTypes:
+ name = NULL;
+ break;
+#endif /* MOZ_LITE */
+ case xpGlobalHistory:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ /* changed to support multi-profile */
+ /*sprintf(newName, "%s\\netscape.hst", theApp.m_pInstallDir->GetCharValue()); */
+ sprintf(newName, "%s\\netscape.hst", (const char *)theApp.m_UserDirectory);
+ break;
+ case xpGlobalHistoryList:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf( newName, "%s\\ns_hstry.htm" );
+ break;
+ case xpKeyChain:
+ name = NULL;
+ break;
+
+ /* larubbio */
+ case xpSARCache:
+ if(!name) {
+ return NULL;
+ }
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\%s", theApp.m_pSARCacheDir, name);
+ break;
+
+ case xpCache:
+ if(!name) {
+ tempName = WH_TempFileName(xpCache, NULL, NULL);
+ if (!tempName) return NULL;
+ name = tempName;
+ }
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ if ((strchr(name,'|') || strchr(name,':'))) { /* Local File URL if find a | */
+ if(name[0] == '/')
+ strcpy(newName,name+1); /* skip past extra slash */
+ else
+ strcpy(newName,name); /* absolute path is valid */
+ } else {
+ sprintf(newName, "%s\\%s", (const char *)theApp.m_pCacheDir, name);
+ }
+ break;
+ case xpBookmarks:
+ case xpHotlist:
+ if (!name || !strlen(name))
+ name = theApp.m_pBookmarkFile;
+ break;
+#endif /* CMD_STUB */
+
+ case xpSocksConfig:
+ prefStr = NULL;
+#ifndef CMD_STUB
+ PREF_CopyCharPref("browser.socksfile_location", &prefStr);
+#else
+ ASSERT(0);
+#endif
+ name = prefStr;
+ break;
+
+#ifndef CMD_STUB
+ case xpCertDB:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ if ( name ) {
+ sprintf(newName, "%s\\cert%s.db", (const char *)theApp.m_UserDirectory, name);
+ } else {
+ sprintf(newName, "%s\\cert.db", (const char *)theApp.m_UserDirectory);
+ }
+ break;
+ case xpCertDBNameIDX:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\certni.db", (const char *)theApp.m_UserDirectory);
+ break;
+ case xpKeyDB:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ if ( name ) {
+ sprintf(newName, "%s\\key%s.db", (const char *)theApp.m_UserDirectory, name);
+ } else {
+ sprintf(newName, "%s\\key.db", (const char *)theApp.m_UserDirectory);
+ }
+ break;
+ case xpSecModuleDB:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\secmod.db", (const char *)theApp.m_UserDirectory);
+ break;
+ case xpSignedAppletDB:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ if ( name ) {
+ sprintf(newName, "%s\\signed%s.db", (const char *)theApp.m_UserDirectory, name);
+ } else {
+ sprintf(newName, "%s\\signed.db", (const char *)theApp.m_UserDirectory);
+ }
+ break;
+#ifndef MOZ_LITE
+ case xpAddrBook:
+#ifdef XP_WIN16
+ if(!name || !strlen(name) )
+ newName = WH_TempName(type, NULL);
+#else
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ strcpy(newName, name);
+
+ /* strip off the extension */
+ {
+ char * pEnd = max(strrchr(newName, '\\'), strrchr(newName, '/'));
+ if(!pEnd)
+ pEnd = newName;
+
+ pEnd = strchr(pEnd, '.');
+ if(pEnd)
+ *pEnd = '\0';
+ }
+ strcat(newName, ".nab");
+#endif
+ break;
+ case xpAddrBookNew:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\%s", (const char *)theApp.m_UserDirectory, name);
+ break;
+ case xpVCardFile:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ strcpy(newName, name);
+
+ /* strip off the extension */
+ {
+ char * pEnd = max(strrchr(newName, '\\'), strrchr(newName, '/'));
+ if(!pEnd)
+ pEnd = newName;
+
+ pEnd = strchr(pEnd, '.');
+ if(pEnd)
+ *pEnd = '\0';
+ }
+ strcat(newName, ".vcf");
+ break;
+ case xpLDIFFile:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ strcpy(newName, name);
+
+ /* strip off the extension */
+ {
+ char * pEnd = max(strrchr(newName, '\\'), strrchr(newName, '/'));
+ if(!pEnd)
+ pEnd = newName;
+
+ pEnd = strchr(pEnd, '.');
+ if(pEnd)
+ *pEnd = '\0';
+ }
+#ifdef XP_WIN16
+ strcat(newName, ".ldi");
+#else
+ strcat(newName, ".ldif");
+#endif
+ break;
+ case xpTemporaryNewsRC:
+ {
+ CString csHostName = g_MsgPrefs.m_csNewsDir;
+ csHostName += "\\news.tmp";
+ newName = XP_STRDUP((const char *) csHostName);
+ }
+ break;
+#endif /* MOZ_LITE */
+ case xpPKCS12File:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ strcpy(newName, name);
+
+ /* strip off the extension */
+ {
+ char * pEnd = max(strrchr(newName, '\\'), strrchr(newName, '/'));
+ if(!pEnd)
+ pEnd = newName;
+
+ pEnd = strchr(pEnd, '.');
+ if(pEnd)
+ *pEnd = '\0';
+ }
+ strcat(newName, ".p12");
+ break;
+ case xpTemporary:
+ if(!name || !strlen(name) )
+ newName = WH_TempName(type, NULL);
+ break;
+#ifndef MOZ_LITE
+ case xpMailFolder:
+ if(!name)
+ name = g_MsgPrefs.m_csMailDir;
+ break;
+ case xpMailFolderSummary:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ strcpy(newName, name);
+
+ /* strip off the extension */
+ {
+ char * pEnd = max(strrchr(newName, '\\'), strrchr(newName, '/'));
+ if(!pEnd)
+ pEnd = newName;
+
+#ifdef XP_WIN16 /* backend won't allow '.' in win16 folder names, but just to be safe. */
+ pEnd = strchr(pEnd, '.');
+ if(pEnd)
+ *pEnd = '\0';
+#endif
+ }
+ strcat(newName, ".snm");
+ break;
+ case xpMailSort:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\rules.dat", (const char *)g_MsgPrefs.m_csMailDir);
+ break;
+ case xpMailFilterLog:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\mailfilt.log", (const char *)g_MsgPrefs.m_csMailDir);
+ break;
+ case xpNewsFilterLog:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\newsfilt.log", (const char *)g_MsgPrefs.m_csNewsDir);
+ break;
+ case xpMailPopState:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\popstate.dat", (const char *)g_MsgPrefs.m_csMailDir);
+ break;
+ case xpMailSubdirectory:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ strcpy(newName, name);
+
+ /* strip off the trailing slash if any */
+ {
+ char * pEnd = max(strrchr(newName, '\\'), strrchr(newName, '/'));
+ if(!pEnd)
+ pEnd = newName;
+ }
+
+ strcat(newName, ".sbd");
+ break;
+#endif /* MOZ_LITE */
+ /* name of global cross-platform registry */
+ case xpRegistry:
+ /* eventually need to support arbitrary names; this is the default */
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ if ( newName != NULL ) {
+ GetWindowsDirectory(newName, _MAX_PATH);
+ int namelen = strlen(newName);
+ if ( newName[namelen-1] == '\\' )
+ namelen--;
+ strcpy(newName+namelen, "\\nsreg.dat");
+ }
+ break;
+ /* name of news group database */
+#ifndef MOZ_LITE
+ case xpXoverCache:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\%s", (const char *)g_MsgPrefs.m_csNewsDir, name);
+ break;
+#endif /* MOZ_LITE */
+ case xpProxyConfig:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ /*sprintf(newName, "%s\\proxy.cfg", theApp.m_pInstallDir->GetCharValue()); */
+ sprintf(newName, "%s\\proxy.cfg", (const char *)theApp.m_UserDirectory);
+ break;
+
+ /* add any cases where no modification is necessary here */
+ /* The name is fine all by itself, no need to modify it */
+ case xpFileToPost:
+ case xpExtCache:
+ case xpURL:
+ /* name is OK as it is */
+ break;
+#ifndef MOZ_LITE
+ case xpNewsHostDatabase:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ sprintf(newName, "%s\\news.db", (const char *)g_MsgPrefs.m_csNewsDir);
+ break;
+
+ case xpImapRootDirectory:
+ newName = PR_smprintf ("%s\\ImapMail", (const char *)theApp.m_UserDirectory);
+ break;
+ case xpImapServerDirectory:
+ {
+ int len = 0;
+ char *tempImapServerDir = XP_STRDUP(name);
+ char *imapServerDir = tempImapServerDir;
+#ifdef XP_WIN16
+ if ((len = XP_STRLEN(imapServerDir)) > 8) {
+ imapServerDir = imapServerDir + len - 8;
+ }
+#endif
+ newName = PR_smprintf ("%s\\ImapMail\\%s", (const char *)theApp.m_UserDirectory, imapServerDir);
+ if (tempImapServerDir) XP_FREE(tempImapServerDir);
+ }
+ break;
+
+ case xpJSMailFilters:
+ newName = PR_smprintf("%s\\filters.js", (const char *)g_MsgPrefs.m_csMailDir);
+ break;
+#endif /* MOZ_LITE */
+ case xpFolderCache:
+ newName = PR_smprintf ("%s\\summary.dat", (const char *)theApp.m_UserDirectory);
+ break;
+
+ case xpCryptoPolicy:
+ newName = (char *) XP_ALLOC(_MAX_PATH);
+ FE_GetProgramDirectory(newName, _MAX_PATH);
+ strcat(newName, "moz40p3");
+ break;
+#endif /* CMD_STUB */
+
+ default:
+ ASSERT(0); /* all types should be covered */
+ break;
+ }
+
+#ifndef MOZ_LITE
+ /* make sure we have the correct newsrc file registered for next time */
+ if((type == xpSNewsRC || type == xpNewsRC) && bNeedToRegister)
+ NET_RegisterNewsrcFile(newName, (char *)name, (type == xpSNewsRC), FALSE );
+#endif
+
+ /* determine what file we are supposed to load and make sure it looks */
+ /* like a DOS pathname and not some unix-like name */
+ if(newName) {
+ *myName = XP_NetToDosFileName((const char*)newName);
+ XP_FREE(newName);
+ } else {
+ *myName = XP_NetToDosFileName((const char*)name);
+ }
+
+ if (tempName) XP_FREE(tempName);
+
+ if (prefStr) XP_FREE(prefStr);
+
+ /* whee, we're done */
+ return(*myName);
+}
+
+/* */
+/* Open a file with the given name */
+/* If a special file type is provided we might need to get the name */
+/* out of the preferences list */
+/* */
+PUBLIC XP_File
+XP_FileOpen(const char * name, XP_FileType type, const XP_FilePerm perm)
+{
+ XP_File fp;
+ char *filename = WH_FileName(name, type);
+
+ if(!filename)
+ return(NULL);
+
+#ifdef DEBUG_nobody
+ TRACE("Opening a file type (%d) permissions: %s (%s)\n", type, perm, filename);
+#endif
+
+#ifdef XP_WIN32
+ if (type == xpURL) {
+ HANDLE hFile;
+ DWORD dwType;
+
+ /* Check if we're trying to open a device. We don't allow this */
+ hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, NULL);
+
+ if (hFile != INVALID_HANDLE_VALUE) {
+ dwType = GetFileType(hFile);
+ CloseHandle(hFile);
+
+ if (dwType != FILE_TYPE_DISK) {
+ XP_FREE(filename);
+ return NULL;
+ }
+ }
+ }
+#endif
+
+#ifdef XP_WIN16
+ /* Windows uses ANSI codepage, DOS uses OEM codepage, */
+ /* fopen takes OEM codepage */
+ /* That's why we need to do conversion here. */
+ CString oembuff = filename;
+ oembuff.AnsiToOem();
+ fp = fopen(oembuff, (char *) perm);
+
+ if (fp && type == xpURL) {
+ union _REGS inregs, outregs;
+
+ /* Check if we opened a device. Execute an Interrupt 21h to invoke */
+ /* MS-DOS system call 44h */
+ inregs.x.ax = 0x4400; /* MS-DOS function to get device information */
+ inregs.x.bx = _fileno(fp);
+ _int86(0x21, &inregs, &outregs);
+
+ if (outregs.x.dx & 0x80) {
+ /* It's a device. Don't allow any reading/writing */
+ fclose(fp);
+ XP_FREE(filename);
+ return NULL;
+ }
+ }
+#else
+ fp = fopen(filename, (char *) perm);
+#endif
+ XP_FREE(filename);
+ return(fp);
+}
+
+
+
+/******************************************************************************/
+/* Thread-safe entry points: */
+
+extern PRMonitor* _pr_TempName_lock;
+
+#ifndef CMD_STUB
+
+char *
+WH_TempName(XP_FileType type, const char * prefix)
+{
+ static char buf[_MAX_PATH]; /* protected by _pr_TempName_lock */
+ char* result;
+
+ if (_pr_TempName_lock == NULL)
+ _pr_TempName_lock = PR_NewNamedMonitor("TempName-lock");
+ PR_EnterMonitor(_pr_TempName_lock);
+
+ result = XP_STRDUP(xp_TempFileName(type, prefix, NULL, buf));
+
+ PR_ExitMonitor(_pr_TempName_lock);
+
+ return result;
+}
+
+#endif /* CMD_STUB */
+
+PUBLIC char *
+WH_FileName (const char *name, XP_FileType type)
+{
+ char* myName;
+ char* result;
+ /*
+ ** I'm not sure this lock is really needed by windows, but just
+ ** to be safe:
+ */
+ /* XP_ASSERT(_pr_TempName_lock); */
+ /* PR_EnterMonitor(_pr_TempName_lock); */
+ result = xp_FileName(name, type, &myName);
+ /* PR_ExitMonitor(_pr_TempName_lock); */
+ return myName;
+}
+
+#endif /* XP_WIN */
diff --git a/security/nss/cmd/lib/makefile.win b/security/nss/cmd/lib/makefile.win
new file mode 100644
index 000000000..92081a2f8
--- /dev/null
+++ b/security/nss/cmd/lib/makefile.win
@@ -0,0 +1,66 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+include <manifest.mn>
+
+include <$(DEPTH)\config\config.mak>
+
+# include files are aought in LINCS and INCS.
+# LINCS are generated from REQUIRES in manigest.mn
+INCS = $(INCS) \
+ -I..\include \
+ -I..\..\lib\cert \
+ $(NULL)
+
+IGNORE_ME = \
+ -I$(DEPTH)\dist\public\security \
+ -I$(DEPTH)\dist\public\nspr \
+ -I$(DEPTH)\cmd\winfe \
+ $(NULL)
+
+LCFLAGS = -DUSE_SSL -DEXPORT_VERSION
+
+PDBFILE = $(LIBNAME).pdb
+
+# work around a bug in rules.mak
+LIBRARY_SUFFIX = $(MOZ_BITS)
+
+include <$(DEPTH)\config\rules.mak>
+
+install:: $(LIBRARY)
+# $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
+
+
+symbols::
+ @echo "LIBRARY_NAME is $(LIBRARY_NAME)"
+ @echo "LIBRARY is $(LIBRARY)"
diff --git a/security/nss/cmd/lib/manifest.mn b/security/nss/cmd/lib/manifest.mn
new file mode 100644
index 000000000..969596863
--- /dev/null
+++ b/security/nss/cmd/lib/manifest.mn
@@ -0,0 +1,68 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+CORE_DEPTH = ../../..
+
+LIBRARY_NAME = sectool
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = seccmd
+
+DEFINES = -DNSPR20
+
+EXPORTS = secutil.h \
+ $(NULL)
+
+CSRCS = secutil.c \
+ secpwd.c \
+ derprint.c \
+ secerror.c \
+ seccnames.c \
+ ffs.c \
+ $(NULL)
+
+OLD_CSRCS = dongle.c \
+ derprint.c \
+ err.c \
+ fe_util.c \
+ ffs.c \
+ filestub.c \
+ secarb.c \
+ secpwd.c \
+ secutil.c \
+ sslstubs.c \
+ strerror.c \
+ stubs.c \
+ $(NULL)
+
+REQUIRES = security nspr dbm
+
diff --git a/security/nss/cmd/lib/secarb.c b/security/nss/cmd/lib/secarb.c
new file mode 100644
index 000000000..176fcbf8b
--- /dev/null
+++ b/security/nss/cmd/lib/secarb.c
@@ -0,0 +1,372 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secutil.h"
+
+#ifdef __sun
+extern int fprintf(FILE *strm, const char *format, .../* args */);
+extern int fflush(FILE *stream);
+#endif
+
+#define RIGHT_MARGIN 24
+/*#define RAW_BYTES 1 */
+
+typedef unsigned char Byte;
+
+static int prettyColumn; /* NOTE: This is NOT reentrant. */
+
+static char *prettyTagType [32] = {
+ "End of Contents", "Boolean", "Integer", "Bit String", "Octet String",
+ "NULL", "Object Identifier", "0x07", "0x08", "0x09", "0x0A",
+ "0x0B", "0X0C", "0X0D", "0X0E", "0X0F", "Sequence", "Set",
+ "0x12", "Printable String", "T61 String", "0x15", "IA5 String",
+ "UTCTime",
+ "0x18", "0x19", "0x1A", "0x1B", "0x1C", "0x1D", "0x1E",
+ "High-Tag-Number"
+};
+
+static SECStatus prettyNewline(FILE *out)
+{
+ int rv;
+
+ if (prettyColumn != -1) {
+ rv = fprintf(out, "\n");
+ prettyColumn = -1;
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+static SECStatus prettyIndent(FILE *out, unsigned level)
+{
+ unsigned i;
+ SECStatus rv;
+
+ if (prettyColumn == -1) {
+ prettyColumn = level;
+ for (i = 0; i < level; i++) {
+ rv = (SECStatus) fprintf(out, " ");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+ }
+ }
+ return SECSuccess;
+}
+
+static SECStatus prettyPrintByte(FILE *out, Byte item, unsigned level)
+{
+ SECStatus rv;
+
+ rv = prettyIndent(out, level);
+ if (rv) return rv;
+
+ rv = (SECStatus) fprintf(out, "%02x ", item);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+ prettyColumn++;
+ if (prettyColumn >= RIGHT_MARGIN) {
+ rv = prettyNewline(out);
+ return rv;
+ }
+ return SECSuccess;
+}
+
+static SECStatus prettyPrintCString(FILE *out, char *str, unsigned level)
+{
+ SECStatus rv;
+
+ rv = prettyNewline(out);
+ if (rv) return rv;
+
+ rv = prettyIndent(out, level);
+ if (rv) return rv;
+
+ rv = (SECStatus) fprintf(out, str);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ rv = prettyNewline(out);
+ return rv;
+}
+
+static SECStatus prettyPrintLeafString(FILE *out, SECArb *arb, unsigned lv)
+{
+ unsigned char buf[100];
+ SECStatus rv;
+ int length = arb->body.item.len;
+
+ if (length > 0 && arb->body.item.data == NULL)
+ return prettyPrintCString(out, "(string contents not available)", lv);
+
+ if (length >= sizeof(buf))
+ length = sizeof(buf) - 1;
+
+ rv = prettyNewline(out);
+ if (rv) return rv;
+
+ rv = prettyIndent(out, lv);
+ if (rv) return rv;
+
+ memcpy(buf, arb->body.item.data, length);
+ buf[length] = '\000';
+
+ rv = (SECStatus) fprintf(out, "\"%s\"", buf);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+ rv = prettyNewline(out);
+ if (rv) return rv;
+
+ return SECSuccess;
+}
+
+static SECStatus prettyPrintLeaf(FILE *out, SECArb* arb, unsigned lv)
+{
+ unsigned i;
+ SECStatus rv;
+ Byte *data = arb->body.item.data;
+
+ if (data == NULL && arb->body.item.len > 0)
+ return prettyPrintCString(out, "(data not availabe)", lv);
+
+ for (i = 0; i < arb->body.item.len; i++) {
+ rv = prettyPrintByte(out, *data++, lv);
+ if (rv) return rv;
+ }
+
+ rv = prettyNewline(out);
+ return rv;
+}
+
+static SECStatus prettyPrintEndContents(FILE *out, unsigned level)
+{
+ return prettyPrintCString(out, prettyTagType[0], level);
+}
+
+static SECStatus prettyPrintTag(FILE *out, SECArb *arb, unsigned level)
+{
+ int rv;
+
+#ifdef RAW_BYTES
+ if (prettyPrintByte(out, arb->tag, level)) return PR_TRUE;
+#else
+ if (prettyIndent(out, level)) return PR_TRUE;
+#endif
+
+ if (arb->tag & DER_CONSTRUCTED) {
+ rv = fprintf(out, "C-");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return PR_TRUE;
+ }
+ }
+
+ switch(arb->tag & 0xC0) {
+ case DER_UNIVERSAL:
+ rv = fprintf(out, "%s ", prettyTagType[arb->tag & 0x17]);
+ break;
+ case DER_APPLICATION:
+ rv = fprintf(out, "Application: %d ", arb->tag & 0x17);
+ break;
+ case DER_CONTEXT_SPECIFIC:
+ rv = fprintf(out, "[%d] ", arb->tag & 0x17);
+ break;
+ case DER_PRIVATE:
+ rv = fprintf(out, "Private: %d ", arb->tag & 0x17);
+ break;
+ }
+
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+static SECStatus prettyPrintLength(FILE *out, SECArb *arb, unsigned lv)
+{
+ int rv = fprintf(out, " (%d)\n", arb->length);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return -1;
+ }
+ prettyColumn = -1;
+ return PR_FALSE;
+}
+
+static SECStatus prettyPrint(FILE *out, SECArb *arb, unsigned lv)
+{
+ int i;
+
+ prettyPrintTag(out, arb, lv);
+ prettyPrintLength(out, arb, lv);
+
+ if (arb->tag & DER_CONSTRUCTED) {
+ for (i = 0; i < arb->body.cons.numSubs; i++)
+ prettyPrint(out, arb->body.cons.subs[i], lv + 1);
+ if (arb->length == 0)
+ prettyPrintEndContents(out, lv);
+ } else {
+ if (arb->tag == DER_PRINTABLE_STRING || arb->tag == DER_UTC_TIME) {
+ if (prettyPrintLeafString(out, arb, lv+1)) return PR_TRUE;
+#ifdef RAW_BYTES
+ if (prettyPrintLeaf(out, arb, lv+1)) return PR_TRUE;
+#endif
+ } else {
+ if (prettyPrintLeaf(out, arb, lv+1)) return PR_TRUE;
+ }
+ }
+
+ return prettyNewline(out);
+}
+
+SECStatus BER_PrettyPrintArb(FILE *out, SECArb *a)
+{
+ prettyColumn = -1;
+ return prettyPrint(out, a, 0);
+}
+
+/*
+ * PackHeader puts the tag and length field into a buffer provided by the
+ * client. It assumes the client has made the buffer at least big
+ * enough. (8 bytes will suffice for now). It returns the number of
+ * valid bytes
+ */
+static int PackHeader(SECArb *arb, unsigned char *header)
+{
+ int tagBytes, lengthBytes;
+ unsigned long length = arb->length;
+ /*
+ * XXX only handles short form tags
+ */
+ header[0] = arb->tag;
+ tagBytes = 1;
+
+ if (length < 0x80) {
+ if ((arb->tag & DER_CONSTRUCTED) && (arb->length == 0))
+ header[tagBytes] = 0x80; /* indefinite length form */
+ else
+ header[tagBytes] = arb->length;
+ lengthBytes = 1;
+ } else {
+ int i;
+ lengthBytes = 0;
+ for (i = 0; i < 4; i++) {
+ if ((length & 0xFF000000) || (lengthBytes > 0)) {
+ header[tagBytes + lengthBytes + 1] = length >> 24;
+ lengthBytes++;
+ }
+ length <<= 8;
+ }
+ header[tagBytes] = 0x80 + lengthBytes;
+ lengthBytes++; /* allow for the room for the length length */
+ }
+ return tagBytes + lengthBytes;
+}
+
+SECStatus BER_Unparse(SECArb *arb, BERUnparseProc proc, void *instance)
+{
+ int i, length;
+ SECStatus rv;
+ unsigned char header[12];
+
+ length = PackHeader(arb, header);
+ rv = (*proc)(instance, header, length, arb);
+ if (rv) return rv;
+
+ if (arb->tag & DER_CONSTRUCTED) {
+ for (i = 0; i < arb->body.cons.numSubs; i++) {
+ rv = BER_Unparse(arb->body.cons.subs[i], proc, instance);
+ if (rv) return rv;
+ }
+ if (arb->length == 0) {
+ rv = (*proc)(instance, "\0\0", 2, arb);
+ if (rv) return rv;
+ }
+ } else {
+ if ((arb->length > 0) && (arb->body.item.data == NULL))
+ return SECFailure;
+ if (arb->length != arb->body.item.len)
+ return SECFailure;
+ rv = (*proc)(instance, arb->body.item.data, arb->length, arb);
+ }
+ return SECSuccess;
+}
+
+static int ResolveLength(SECArb *arb)
+{
+ int length, i, rv;
+ unsigned char header[12];
+
+ /*
+ * One theory is that there might be valid subtrees along with
+ * still yet uknown length trees. That would imply that the scan
+ * should not be aborted on first failure.
+ */
+
+ length = PackHeader(arb, header);
+ if (arb->tag | DER_CONSTRUCTED) {
+ if (arb->length > 0)
+ length += arb->length;
+ else {
+ for (i = 0; i < arb->body.cons.numSubs; i++) {
+ rv = ResolveLength(arb->body.cons.subs[i]);
+ if (rv < 0) return -1;
+ length += rv;
+ }
+ arb->length = length;
+ }
+ } else {
+ if (arb->length != arb->body.item.len)
+ return -1;
+ length += arb->length;
+ }
+ return length;
+}
+
+SECStatus BER_ResolveLengths(SECArb *arb)
+{
+ int rv;
+ rv = ResolveLength(arb);
+ if (rv < 0) return SECFailure;
+ return SECSuccess;
+}
diff --git a/security/nss/cmd/lib/seccnames.c b/security/nss/cmd/lib/seccnames.c
new file mode 100644
index 000000000..a1857dc0e
--- /dev/null
+++ b/security/nss/cmd/lib/seccnames.c
@@ -0,0 +1,204 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+/*
+** secutil.c - various functions used by security stuff
+**
+*/
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+
+#include "secutil.h"
+#include "secpkcs7.h"
+#include "secrng.h"
+#if !defined(_WIN32_WCE)
+#include <sys/stat.h>
+#endif
+#include <stdarg.h>
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+
+/* for SEC_TraverseNames */
+#include "cert.h"
+#include "certt.h"
+#include "certdb.h"
+
+typedef struct {
+ char * name;
+ CERTCertTrust trust;
+} certNameAndTrustEntry;
+
+typedef struct {
+ int numCerts;
+ certNameAndTrustEntry *nameAndTrustEntries;
+} certNameAndTrustList;
+
+SECStatus
+sec_CountCerts(CERTCertificate *cert, SECItem *unknown, void *arg)
+{
+ (*(int*)arg)++;
+ return SECSuccess;
+}
+
+SECStatus
+sec_CollectCertNamesAndTrust(CERTCertificate *cert, SECItem *unknown, void *arg)
+{
+ certNameAndTrustList *pCertNames = (certNameAndTrustList*)arg;
+ char *name;
+ int i;
+
+ i = pCertNames->numCerts;
+ name = cert->nickname ? cert->nickname : cert->emailAddr;
+
+ if (name)
+ pCertNames->nameAndTrustEntries[i].name = PORT_Strdup(name);
+ else
+ pCertNames->nameAndTrustEntries[i].name = PORT_Strdup("<unknown>");
+
+ PORT_Memcpy(&pCertNames->nameAndTrustEntries[i].trust, cert->trust, sizeof(*cert->trust));
+
+ pCertNames->numCerts++;
+
+ return SECSuccess;
+}
+
+
+static int
+sec_name_and_trust_compare_by_name(const void *p1, const void *p2)
+{
+ certNameAndTrustEntry *e1 = (certNameAndTrustEntry *)p1;
+ certNameAndTrustEntry *e2 = (certNameAndTrustEntry *)p2;
+ return PORT_Strcmp(e1->name, e2->name);
+}
+
+static int
+sec_combine_trust_flags(CERTCertTrust *trust)
+{
+ if (trust == NULL)
+ return 0;
+ return trust->sslFlags | trust->emailFlags | trust->objectSigningFlags;
+}
+
+static int
+sec_name_and_trust_compare_by_trust(const void *p1, const void *p2)
+{
+ certNameAndTrustEntry *e1 = (certNameAndTrustEntry *)p1;
+ certNameAndTrustEntry *e2 = (certNameAndTrustEntry *)p2;
+ int e1_is_ca, e2_is_ca;
+ int e1_is_user, e2_is_user;
+ int rv;
+
+ e1_is_ca = (sec_combine_trust_flags(&e1->trust) & CERTDB_VALID_CA) != 0;
+ e2_is_ca = (sec_combine_trust_flags(&e2->trust) & CERTDB_VALID_CA) != 0;
+ e1_is_user = (sec_combine_trust_flags(&e1->trust) & CERTDB_USER) != 0;
+ e2_is_user = (sec_combine_trust_flags(&e2->trust) & CERTDB_USER) != 0;
+
+ /* first, sort by user status, then CA status, */
+ /* then by actual comparison of CA flags, then by name */
+ if ((rv = (e2_is_user - e1_is_user)) == 0 && (rv = (e1_is_ca - e2_is_ca)) == 0)
+ if (e1_is_ca || (rv = memcmp(&e1->trust, &e2->trust, sizeof(CERTCertTrust))) == 0)
+ return PORT_Strcmp(e1->name, e2->name);
+ else
+ return rv;
+ else
+ return rv;
+}
+
+SECStatus
+SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc *out,
+ PRBool sortByName, PRBool sortByTrust)
+{
+ certNameAndTrustList certNames = { 0, NULL };
+ int numCerts, i;
+ SECStatus rv;
+ int (*comparefn)(const void *, const void *);
+ char trusts[30];
+
+ numCerts = 0;
+
+ rv = SEC_TraversePermCerts(handle, sec_CountCerts, &numCerts);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ certNames.nameAndTrustEntries =
+ (certNameAndTrustEntry *)PORT_Alloc(numCerts * sizeof(certNameAndTrustEntry));
+ if (certNames.nameAndTrustEntries == NULL)
+ return SECFailure;
+
+ rv = SEC_TraversePermCerts(handle, sec_CollectCertNamesAndTrust, &certNames);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ if (sortByName)
+ comparefn = sec_name_and_trust_compare_by_name;
+ else if (sortByTrust)
+ comparefn = sec_name_and_trust_compare_by_trust;
+ else
+ comparefn = NULL;
+
+ if (comparefn)
+ qsort(certNames.nameAndTrustEntries, certNames.numCerts,
+ sizeof(certNameAndTrustEntry), comparefn);
+
+ PR_fprintf(out, "\n%-60s %-5s\n\n", "Certificate Name", "Trust Attributes");
+ for (i = 0; i < certNames.numCerts; i++) {
+ PORT_Memset (trusts, 0, sizeof(trusts));
+ printflags(trusts, certNames.nameAndTrustEntries[i].trust.sslFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, certNames.nameAndTrustEntries[i].trust.emailFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, certNames.nameAndTrustEntries[i].trust.objectSigningFlags);
+ PR_fprintf(out, "%-60s %-5s\n",
+ certNames.nameAndTrustEntries[i].name, trusts);
+ }
+ PR_fprintf(out, "\n");
+ PR_fprintf(out, "p Valid peer\n");
+ PR_fprintf(out, "P Trusted peer (implies p)\n");
+ PR_fprintf(out, "c Valid CA\n");
+ PR_fprintf(out, "T Trusted CA to issue client certs (implies c)\n");
+ PR_fprintf(out, "C Trusted CA to certs(only server certs for ssl) (implies c)\n");
+ PR_fprintf(out, "u User cert\n");
+ PR_fprintf(out, "w Send warning\n");
+
+ for (i = 0; i < certNames.numCerts; i++)
+ PORT_Free(certNames.nameAndTrustEntries[i].name);
+ PORT_Free(certNames.nameAndTrustEntries);
+
+ return rv;
+}
diff --git a/security/nss/cmd/lib/secerror.c b/security/nss/cmd/lib/secerror.c
new file mode 100644
index 000000000..857704b79
--- /dev/null
+++ b/security/nss/cmd/lib/secerror.c
@@ -0,0 +1,107 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "nspr.h"
+
+struct tuple_str {
+ PRErrorCode errNum;
+ const char * errString;
+};
+
+typedef struct tuple_str tuple_str;
+
+#define ER2(a,b) {a, b},
+#define ER3(a,b,c) {a, c},
+
+#include "secerr.h"
+#include "sslerr.h"
+
+const tuple_str errStrings[] = {
+
+/* keep this list in asceding order of error numbers */
+#include "SSLerrs.h"
+#include "SECerrs.h"
+#include "NSPRerrs.h"
+
+};
+
+const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str);
+
+/* Returns a UTF-8 encoded constant error string for "errNum".
+ * Returns NULL of errNum is unknown.
+ */
+const char *
+SECU_Strerror(PRErrorCode errNum) {
+ PRInt32 low = 0;
+ PRInt32 high = numStrings - 1;
+ PRInt32 i;
+ PRErrorCode num;
+ static int initDone;
+
+ /* make sure table is in ascending order.
+ * binary search depends on it.
+ */
+ if (!initDone) {
+ PRErrorCode lastNum = ((PRInt32)0x80000000);
+ for (i = low; i <= high; ++i) {
+ num = errStrings[i].errNum;
+ if (num <= lastNum) {
+ fprintf(stderr,
+"sequence error in error strings at item %d\n"
+"error %d (%s)\n"
+"should come after \n"
+"error %d (%s)\n",
+ i, lastNum, errStrings[i-1].errString,
+ num, errStrings[i].errString);
+ }
+ lastNum = num;
+ }
+ initDone = 1;
+ }
+
+ /* Do binary search of table. */
+ while (low + 1 < high) {
+ i = (low + high) / 2;
+ num = errStrings[i].errNum;
+ if (errNum == num)
+ return errStrings[i].errString;
+ if (errNum < num)
+ high = i;
+ else
+ low = i;
+ }
+ if (errNum == errStrings[low].errNum)
+ return errStrings[low].errString;
+ if (errNum == errStrings[high].errNum)
+ return errStrings[high].errString;
+ return NULL;
+}
diff --git a/security/nss/cmd/lib/secpwd.c b/security/nss/cmd/lib/secpwd.c
new file mode 100644
index 000000000..8bc4eef14
--- /dev/null
+++ b/security/nss/cmd/lib/secpwd.c
@@ -0,0 +1,193 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secutil.h"
+
+/*
+ * NOTE: The contents of this file are NOT used by the client.
+ * (They are part of the security library as a whole, but they are
+ * NOT USED BY THE CLIENT.) Do not change things on behalf of the
+ * client (like localizing strings), or add things that are only
+ * for the client (put them elsewhere).
+ */
+
+
+#ifdef XP_UNIX
+#include <termios.h>
+#include <unistd.h>
+#endif
+
+#if defined(_WINDOWS) && !defined(_WIN32_WCE)
+#include <conio.h>
+#include <io.h>
+#define QUIET_FGETS quiet_fgets
+static char * quiet_fgets (char *buf, int length, FILE *input);
+#else
+#define QUIET_FGETS fgets
+#endif
+
+static void echoOff(int fd)
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag &= ~ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+static void echoOn(int fd)
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag |= ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
+ PRBool (*ok)(char *))
+{
+#if defined(_WINDOWS) || defined(OS2)
+ int isTTY = (input == stdin);
+#define echoOn(x)
+#define echoOff(x)
+#else
+ int infd = fileno(input);
+ int isTTY = isatty(infd);
+#endif
+ char phrase[200];
+
+ for (;;) {
+ /* Prompt for password */
+ if (isTTY) {
+ fprintf(output, "%s", prompt);
+ fflush (output);
+ echoOff(infd);
+ }
+
+ QUIET_FGETS ( phrase, sizeof(phrase), input);
+
+ if (isTTY) {
+ fprintf(output, "\n");
+ echoOn(infd);
+ }
+
+ /* stomp on newline */
+ phrase[PORT_Strlen(phrase)-1] = 0;
+
+ /* Validate password */
+ if (!(*ok)(phrase)) {
+ /* Not weird enough */
+ if (!isTTY) return 0;
+ fprintf(output, "Password must be at least 8 characters long with one or more\n");
+ fprintf(output, "non-alphabetic characters\n");
+ continue;
+ }
+ return (char*) PORT_Strdup(phrase);
+ }
+}
+
+
+
+PRBool SEC_CheckPassword(char *cp)
+{
+ int len;
+ char *end;
+
+ len = PORT_Strlen(cp);
+ if (len < 8) {
+ return PR_FALSE;
+ }
+ end = cp + len;
+ while (cp < end) {
+ unsigned char ch = *cp++;
+ if (!((ch >= 'A') && (ch <= 'Z')) &&
+ !((ch >= 'a') && (ch <= 'z'))) {
+ /* pass phrase has at least one non alphabetic in it */
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+PRBool SEC_BlindCheckPassword(char *cp)
+{
+ if (cp != NULL) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+/* Get a password from the input terminal, without echoing */
+
+#ifdef _WINDOWS
+static char * quiet_fgets (char *buf, int length, FILE *input)
+ {
+ int c;
+ char *end = buf;
+
+ /* fflush (input); */
+ memset (buf, 0, length);
+
+ if (input != stdin) {
+ return fgets(buf,length,input);
+ }
+
+ while (1)
+ {
+#if defined (_WIN32_WCE)
+ c = getchar(); /* gets a character from stdin */
+#else
+ c = getch(); /* getch gets a character from the console */
+#endif
+ if (c == '\b')
+ {
+ if (end > buf)
+ end--;
+ }
+
+ else if (--length > 0)
+ *end++ = c;
+
+ if (!c || c == '\n' || c == '\r')
+ break;
+ }
+
+ return buf;
+ }
+#endif
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
new file mode 100644
index 000000000..6b9ab8e3c
--- /dev/null
+++ b/security/nss/cmd/lib/secutil.c
@@ -0,0 +1,2593 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+/*
+** secutil.c - various functions used by security stuff
+**
+*/
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+
+#include "secutil.h"
+#include "secpkcs7.h"
+#include "secrng.h"
+#include <stdarg.h>
+#if !defined(_WIN32_WCE)
+#include <sys/stat.h>
+#include <errno.h>
+#endif
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+
+/* for SEC_TraverseNames */
+#include "cert.h"
+#include "certt.h"
+#include "certdb.h"
+
+/* #include "secmod.h" */
+#include "pk11func.h"
+#include "secoid.h"
+
+static char consoleName[] = {
+#ifdef XP_UNIX
+#ifdef VMS
+ "TT"
+#else
+ "/dev/tty"
+#endif
+#else
+ "CON:"
+#endif
+};
+
+char *
+SECU_GetString(int16 error_number)
+{
+
+ static char errString[80];
+ sprintf(errString, "Unknown error string (%d)", error_number);
+ return errString;
+}
+
+void
+SECU_PrintError(char *progName, char *msg, ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char * errString = SECU_Strerror(err);
+
+ va_start(args, msg);
+
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(stderr, ": %s\n", errString);
+ else
+ fprintf(stderr, ": error %d\n", (int)err);
+
+ va_end(args);
+}
+
+void
+SECU_PrintSystemError(char *progName, char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+#if defined(_WIN32_WCE)
+ fprintf(stderr, ": %d\n", PR_GetOSError());
+#else
+ fprintf(stderr, ": %s\n", strerror(errno));
+#endif
+ va_end(args);
+}
+
+static void
+secu_ClearPassword(char *p)
+{
+ if (p) {
+ PORT_Memset(p, 0, PORT_Strlen(p));
+ PORT_Free(p);
+ }
+}
+
+char *
+SECU_GetPasswordString(void *arg, char *prompt)
+{
+#ifndef _WINDOWS
+ char *p = NULL;
+ FILE *input, *output;
+
+ /* open terminal */
+ input = fopen(consoleName, "r");
+ if (input == NULL) {
+ fprintf(stderr, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ fprintf(stderr, "Error opening output terminal for write\n");
+ return NULL;
+ }
+
+ p = SEC_GetPassword (input, output, prompt, SEC_BlindCheckPassword);
+
+
+ fclose(input);
+ fclose(output);
+
+ return p;
+
+#else
+ /* Win32 version of above. opening the console may fail
+ on windows95, and certainly isn't necessary.. */
+
+ char *p = NULL;
+
+ p = SEC_GetPassword (stdin, stdout, prompt, SEC_BlindCheckPassword);
+ return p;
+
+#endif
+}
+
+
+/*
+ * p a s s w o r d _ h a r d c o d e
+ *
+ * A function to use the password passed in the -f(pwfile) argument
+ * of the command line.
+ * After use once, null it out otherwise PKCS11 calls us forever.?
+ *
+ */
+char *
+SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ unsigned char phrase[200];
+ PRFileDesc *fd;
+ PRInt32 nb;
+ char *pwFile = arg;
+ int i;
+
+ if (!pwFile)
+ return 0;
+
+ if (retry) {
+ return 0; /* no good retrying - the files contents will be the same */
+ }
+
+ fd = PR_Open(pwFile, PR_RDONLY, 0);
+ if (!fd) {
+ fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
+ return NULL;
+ }
+
+ nb = PR_Read(fd, phrase, sizeof(phrase));
+
+ PR_Close(fd);
+ /* handle the Windows EOL case */
+ i = 0;
+ while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;
+ phrase[i] = '\0';
+ if (nb == 0) {
+ fprintf(stderr,"password file contains no data\n");
+ return NULL;
+ }
+ return (char*) PORT_Strdup((char*)phrase);
+}
+
+char *
+SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char prompt[255];
+ secuPWData *pwdata = (secuPWData *)arg;
+ secuPWData pwnull = { PW_NONE, 0 };
+ char *pw;
+
+ if (pwdata == NULL)
+ pwdata = &pwnull;
+
+ if (retry && pwdata->source != PW_NONE) {
+ PR_fprintf(PR_STDERR, "incorrect password entered at command line.\n");
+ return NULL;
+ }
+
+ switch (pwdata->source) {
+ case PW_NONE:
+ sprintf(prompt, "Enter Password or Pin for \"%s\":",
+ PK11_GetTokenName(slot));
+ return SECU_GetPasswordString(NULL, prompt);
+ case PW_FROMFILE:
+ /* Instead of opening and closing the file every time, get the pw
+ * once, then keep it in memory (duh).
+ */
+ pw = SECU_FilePasswd(slot, retry, pwdata->data);
+ pwdata->source = PW_PLAINTEXT;
+ pwdata->data = PL_strdup(pw);
+ /* it's already been dup'ed */
+ return pw;
+ case PW_PLAINTEXT:
+ return PL_strdup(pwdata->data);
+ default:
+ break;
+ }
+
+ PR_fprintf(PR_STDERR, "Password check failed: No password found.\n");
+ return NULL;
+}
+
+char *
+secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *p0 = NULL;
+ char *p1 = NULL;
+ FILE *input, *output;
+ secuPWData *pwdata = arg;
+
+ if (pwdata->source == PW_FROMFILE) {
+ return SECU_FilePasswd(slot, retry, pwdata->data);
+ } else if (pwdata->source == PW_PLAINTEXT) {
+ return PL_strdup(pwdata->data);
+ }
+
+ /* PW_NONE - get it from tty */
+ /* open terminal */
+#ifdef _WINDOWS
+ input = stdin;
+#else
+ input = fopen(consoleName, "r");
+#endif
+ if (input == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ /* we have no password, so initialize database with one */
+ PR_fprintf(PR_STDERR, "In order to finish creating your database, you\n");
+ PR_fprintf(PR_STDERR, "must enter a password which will be used to\n");
+ PR_fprintf(PR_STDERR, "encrypt this key and any future keys.\n\n");
+ PR_fprintf(PR_STDERR, "The password must be at least 8 characters long,\n");
+ PR_fprintf(PR_STDERR, "and must contain at least one non-alphabetic ");
+ PR_fprintf(PR_STDERR, "character.\n\n");
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening output terminal for write\n");
+ return NULL;
+ }
+
+
+ for (;;) {
+ if (!p0) {
+ p0 = SEC_GetPassword(input, output, "Enter new password: ",
+ SEC_BlindCheckPassword);
+ }
+ if (pwdata->source == PW_NONE) {
+ p1 = SEC_GetPassword(input, output, "Re-enter password: ",
+ SEC_BlindCheckPassword);
+ }
+ if (pwdata->source != PW_NONE || (PORT_Strcmp(p0, p1) == 0)) {
+ break;
+ }
+ PR_fprintf(PR_STDERR, "Passwords do not match. Try again.\n");
+ }
+
+ /* clear out the duplicate password string */
+ secu_ClearPassword(p1);
+
+ fclose(input);
+ fclose(output);
+
+ return p0;
+}
+
+SECStatus
+SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile)
+{
+ SECStatus rv;
+ secuPWData pwdata, newpwdata;
+ char *oldpw = NULL, *newpw = NULL;
+
+ if (passwd) {
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = passwd;
+ } else if (pwFile) {
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = pwFile;
+ } else {
+ pwdata.source = PW_NONE;
+ pwdata.data = NULL;
+ }
+
+ if (PK11_NeedUserInit(slot)) {
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &pwdata);
+ rv = PK11_InitPin(slot, (char*)NULL, newpw);
+ goto done;
+ }
+
+ for (;;) {
+ oldpw = SECU_GetModulePassword(slot, PR_FALSE, &pwdata);
+
+ if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
+ if (pwdata.source == PW_NONE) {
+ PR_fprintf(PR_STDERR, "Invalid password. Try again.\n");
+ } else {
+ PR_fprintf(PR_STDERR, "Invalid password.\n");
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+ return SECFailure;
+ }
+ } else
+ break;
+
+ PORT_Free(oldpw);
+ }
+
+ newpwdata.source = PW_NONE;
+ newpwdata.data = NULL;
+
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);
+
+ if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
+ PR_fprintf(PR_STDERR, "Failed to change password.\n");
+ return SECFailure;
+ }
+
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+
+ PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
+
+done:
+ PORT_Memset(newpw, 0, PL_strlen(newpw));
+ PORT_Free(newpw);
+ return SECSuccess;
+}
+
+struct matchobj {
+ SECItem index;
+ char *nname;
+ PRBool found;
+};
+
+char *
+SECU_DefaultSSLDir(void)
+{
+ char *dir;
+ static char sslDir[1000];
+
+ dir = PR_GetEnv("SSL_DIR");
+ if (!dir)
+ return NULL;
+
+ sprintf(sslDir, "%s", dir);
+
+ if (sslDir[strlen(sslDir)-1] == '/')
+ sslDir[strlen(sslDir)-1] = 0;
+
+ return sslDir;
+}
+
+char *
+SECU_AppendFilenameToDir(char *dir, char *filename)
+{
+ static char path[1000];
+
+ if (dir[strlen(dir)-1] == '/')
+ sprintf(path, "%s%s", dir, filename);
+ else
+ sprintf(path, "%s/%s", dir, filename);
+ return path;
+}
+
+char *
+SECU_ConfigDirectory(const char* base)
+{
+ static PRBool initted = PR_FALSE;
+ const char *dir = ".netscape";
+ char *home;
+ static char buf[1000];
+
+ if (initted) return buf;
+
+
+ if (base == NULL || *base == 0) {
+ home = PR_GetEnv("HOME");
+ if (!home) home = "";
+
+ if (*home && home[strlen(home) - 1] == '/')
+ sprintf (buf, "%.900s%s", home, dir);
+ else
+ sprintf (buf, "%.900s/%s", home, dir);
+ } else {
+ sprintf(buf, "%.900s", base);
+ if (buf[strlen(buf) - 1] == '/')
+ buf[strlen(buf) - 1] = 0;
+ }
+
+
+ initted = PR_TRUE;
+ return buf;
+}
+
+/*Turn off SSL for now */
+/* This gets called by SSL when server wants our cert & key */
+int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ SECKEYPrivateKey *key;
+ CERTCertificate *cert;
+ int errsave;
+
+ if (arg == NULL) {
+ fprintf(stderr, "no key/cert name specified for client auth\n");
+ return -1;
+ }
+ cert = PK11_FindCertFromNickname(arg, NULL);
+ errsave = PORT_GetError();
+ if (!cert) {
+ if (errsave == SEC_ERROR_BAD_PASSWORD)
+ fprintf(stderr, "Bad password\n");
+ else if (errsave > 0)
+ fprintf(stderr, "Unable to read cert (error %d)\n", errsave);
+ else if (errsave == SEC_ERROR_BAD_DATABASE)
+ fprintf(stderr, "Unable to get cert from database (%d)\n", errsave);
+ else
+ fprintf(stderr, "SECKEY_FindKeyByName: internal error %d\n", errsave);
+ return -1;
+ }
+
+ key = PK11_FindKeyByAnyCert(arg,NULL);
+ if (!key) {
+ fprintf(stderr, "Unable to get key (%d)\n", PORT_GetError());
+ return -1;
+ }
+
+
+ *pRetCert = cert;
+ *pRetKey = key;
+
+ return 0;
+}
+
+SECStatus
+secu_StdinToItem(SECItem *dst)
+{
+ unsigned char buf[1000];
+ PRInt32 numBytes;
+ PRBool notDone = PR_TRUE;
+
+ dst->len = 0;
+ dst->data = NULL;
+
+ while (notDone) {
+ numBytes = PR_Read(PR_STDIN, buf, sizeof(buf));
+
+ if (numBytes < 0) {
+ PORT_SetError(PR_IO_ERROR);
+ return SECFailure;
+ }
+
+ if (numBytes == 0)
+ break;
+
+ if (buf[numBytes-1] == '\n') {
+ buf[numBytes-1] = '\0';
+ notDone = PR_FALSE;
+ }
+
+ if (dst->data) {
+ dst->data = (unsigned char*)PORT_Realloc(dst->data,
+ dst->len+numBytes);
+ PORT_Memcpy(dst->data+dst->len, buf, numBytes);
+ } else {
+ dst->data = (unsigned char*)PORT_Alloc(numBytes);
+ PORT_Memcpy(dst->data, buf, numBytes);
+ }
+ dst->len += numBytes;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+SECU_FileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, info.size))
+ goto loser;
+
+ numBytes = PR_Read(src, dst->data, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ return SECSuccess;
+loser:
+ SECITEM_FreeItem(dst, PR_FALSE);
+ return SECFailure;
+}
+
+SECStatus
+SECU_TextFileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+ unsigned char *buf;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ buf = (unsigned char*)PORT_Alloc(info.size);
+ if (!buf)
+ return SECFailure;
+
+ numBytes = PR_Read(src, buf, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ if (buf[numBytes-1] == '\n') numBytes--;
+#ifdef _WINDOWS
+ if (buf[numBytes-1] == '\r') numBytes--;
+#endif
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, numBytes))
+ goto loser;
+
+ memcpy(dst->data, buf, numBytes);
+
+ PORT_Free(buf);
+ return SECSuccess;
+loser:
+ PORT_Free(buf);
+ return SECFailure;
+}
+
+SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
+{
+ SECStatus rv;
+ char *asc, *body, *trailer;
+ if (ascii) {
+ /* First convert ascii to binary */
+ SECItem filedata;
+
+ /* Read in ascii data */
+ rv = SECU_FileToItem(&filedata, inFile);
+ asc = (char *)filedata.data;
+ if (!asc) {
+ fprintf(stderr, "unable to read data from input file\n");
+ return SECFailure;
+ }
+
+ /* check for headers and trailers and remove them */
+ if ((body = strstr(asc, "-----BEGIN")) != NULL) {
+ body = PORT_Strchr(body, '\n') + 1;
+ trailer = strstr(body, "-----END");
+ if (trailer != NULL) {
+ *trailer = '\0';
+ } else {
+ fprintf(stderr, "input has header but no trailer\n");
+ return SECFailure;
+ }
+ } else {
+ body = asc;
+ }
+
+ /* Convert to binary */
+ rv = ATOB_ConvertAsciiToItem(der, body);
+ if (rv) {
+ fprintf(stderr, "error converting ascii to binary (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ return SECFailure;
+ }
+ PORT_Free(asc);
+ } else {
+ /* Read in binary der */
+ rv = SECU_FileToItem(der, inFile);
+ if (rv) {
+ fprintf(stderr, "error converting der (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+#define INDENT_MULT 4
+void
+SECU_Indent(FILE *out, int level)
+{
+ int i;
+ for (i = 0; i < level; i++) {
+ fprintf(out, " ");
+ }
+}
+
+static void secu_Newline(FILE *out)
+{
+ fprintf(out, "\n");
+}
+
+void
+SECU_PrintAsHex(FILE *out, SECItem *data, char *m, int level)
+{
+ unsigned i;
+ int column;
+ PRBool isString = PR_TRUE;
+
+ if ( m ) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
+ }
+
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ if (isString && val && !isprint(val)) {
+ isString = PR_FALSE;
+ }
+ if (i != data->len - 1) {
+ fprintf(out, "%02x:", data->data[i]);
+ column += 4;
+ } else {
+ fprintf(out, "%02x", data->data[i]);
+ column += 3;
+ break;
+ }
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+ }
+ if (isString) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ if (val) {
+ fprintf(out,"%c",val);
+ column++;
+ } else {
+ column = 77;
+ }
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+ }
+ }
+
+ level--;
+ if (column != level*INDENT_MULT) {
+ secu_Newline(out);
+ }
+}
+
+static const char *hex = "0123456789abcdef";
+
+static const char printable[257] = {
+ "................" /* 0x */
+ "................" /* 1x */
+ " !\"#$%&'()*+,-./" /* 2x */
+ "0123456789:;<=>?" /* 3x */
+ "@ABCDEFGHIJKLMNO" /* 4x */
+ "PQRSTUVWXYZ[\\]^_" /* 5x */
+ "`abcdefghijklmno" /* 6x */
+ "pqrstuvwxyz{|}~." /* 7x */
+ "................" /* 8x */
+ "................" /* 9x */
+ "................" /* ax */
+ "................" /* bx */
+ "................" /* cx */
+ "................" /* dx */
+ "................" /* ex */
+ "................" /* fx */
+};
+
+void
+SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len)
+{
+ const unsigned char *cp = (const unsigned char *)vp;
+ char buf[80];
+ char *bp;
+ char *ap;
+
+ fprintf(out, "%s [Len: %d]\n", msg, len);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ while (--len >= 0) {
+ unsigned char ch = *cp++;
+ *bp++ = hex[(ch >> 4) & 0xf];
+ *bp++ = hex[ch & 0xf];
+ *bp++ = ' ';
+ *ap++ = printable[ch];
+ if (ap - buf >= 66) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ }
+ }
+ if (bp > buf) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ }
+}
+
+void
+SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level)
+{
+ int iv;
+
+ if (i->len > 4) {
+ SECU_PrintAsHex(out, i, m, level);
+ } else {
+ iv = DER_GetInteger(i);
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: %d (0x%x)\n", m, iv, iv);
+ } else {
+ fprintf(out, "%d (0x%x)\n", iv, iv);
+ }
+ }
+}
+
+void
+SECU_PrintString(FILE *out, SECItem *i, char *m, int level)
+{
+ char *string;
+ unsigned char *data = i->data;
+ int len = i->len;
+ int lenlen;
+ int tag;
+
+ string = PORT_ZAlloc(i->len+1);
+
+ tag = *data++; len--;
+ if (data[1] & 0x80) {
+ lenlen = data[1] & 0x1f;
+ } else {
+ lenlen = 1;
+ }
+ data += lenlen; len -= lenlen;
+ if (len <= 0) return;
+ PORT_Memcpy(string,data,len);
+
+ /* should check the validity of tag, and convert the string as necessary */
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: \"%s\"\n", m, string);
+ } else {
+ fprintf(out, "\"%s\"\n", string);
+ }
+}
+
+static void
+secu_PrintBoolean(FILE *out, SECItem *i, char *m, int level)
+{
+ int val = 0;
+
+ if ( i->data ) {
+ val = i->data[0];
+ }
+
+ if (m) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m); level++;
+ }
+ if ( val ) {
+ SECU_Indent(out, level); fprintf(out, "%s\n", "True");
+ } else {
+ SECU_Indent(out, level); fprintf(out, "%s\n", "False");
+ }
+}
+
+/*
+ * Format and print "time". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+static void
+secu_PrintTime(FILE *out, int64 time, char *m, int level)
+{
+ PRExplodedTime printableTime;
+ char *timeString;
+
+ /* Convert to local time */
+ PR_ExplodeTime(time, PR_GMTParameters, &printableTime);
+
+ timeString = PORT_Alloc(100);
+ if (timeString == NULL)
+ return;
+
+ if (m != NULL) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", m);
+ }
+
+ PR_FormatTime(timeString, 100, "%a %b %d %H:%M:%S %Y", &printableTime);
+ fprintf(out, timeString);
+
+ if (m != NULL)
+ fprintf(out, "\n");
+
+ PORT_Free(timeString);
+}
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintUTCTime(FILE *out, SECItem *t, char *m, int level)
+{
+ int64 time;
+ SECStatus rv;
+
+ rv = DER_UTCTimeToTime(&time, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time, m, level);
+}
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintGeneralizedTime(FILE *out, SECItem *t, char *m, int level)
+{
+ int64 time;
+ SECStatus rv;
+
+
+ rv = DER_GeneralizedTimeToTime(&time, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time, m, level);
+}
+
+static void secu_PrintAny(FILE *out, SECItem *i, char *m, int level);
+
+void
+SECU_PrintSet(FILE *out, SECItem *t, char *m, int level)
+{
+ int type= t->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int start;
+ unsigned char *bp;
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+
+ fprintf(out,"%s {\n", type == SEC_ASN1_SET ? "Set" : "Sequence"); /* } */
+
+ start = 2;
+ if (t->data[1] & 0x80) {
+ start += (t->data[1] & 0x7f);
+ }
+ for (bp=&t->data[start]; bp < &t->data[t->len]; ) {
+ SECItem tmp;
+ unsigned int i,len,lenlen;
+
+ if (bp[1] & 0x80) {
+ lenlen = bp[1] & 0x1f;
+ len = 0;
+ for (i=0; i < lenlen; i++) {
+ len = len * 255 + bp[2+i];
+ }
+ } else {
+ lenlen = 1;
+ len = bp[1];
+ }
+ tmp.len = len+lenlen+1;
+ if (tmp.len > &t->data[t->len] - bp) {
+ tmp.len = &t->data[t->len] - bp;
+ }
+ tmp.data = bp;
+ bp += tmp.len;
+ secu_PrintAny(out,&tmp,NULL,level+1);
+ }
+ /* { */SECU_Indent(out, level); fprintf(out, "}\n");
+}
+static void
+secu_PrintContextSpecific(FILE *out, SECItem *i, char *m, int level)
+{
+ int type= i->data[0] & SEC_ASN1_TAGNUM_MASK;
+ SECItem tmp;
+ int start;
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+
+ fprintf(out,"Option %d\n", type);
+ start = 2;
+ if (i->data[1] & 0x80) {
+ start = (i->data[1] & 0x7f) +1;
+ }
+ tmp.data = &i->data[start];
+ tmp.len = i->len -start;
+ SECU_PrintAsHex(out, &tmp, m, level+1);
+}
+
+static void
+secu_PrintUniversal(FILE *out, SECItem *i, char *m, int level)
+{
+ switch (i->data[0] & SEC_ASN1_TAGNUM_MASK) {
+ case SEC_ASN1_INTEGER:
+ SECU_PrintInteger(out, i, m, level);
+ break;
+ case SEC_ASN1_OBJECT_ID:
+ SECU_PrintObjectID(out, i, m, level);
+ break;
+ case SEC_ASN1_BOOLEAN:
+ secu_PrintBoolean(out, i, m, level);
+ break;
+ case SEC_ASN1_UTF8_STRING:
+ case SEC_ASN1_PRINTABLE_STRING:
+ case SEC_ASN1_VISIBLE_STRING:
+ case SEC_ASN1_BMP_STRING:
+ case SEC_ASN1_IA5_STRING:
+ case SEC_ASN1_T61_STRING:
+ case SEC_ASN1_UNIVERSAL_STRING:
+ SECU_PrintString(out, i, m, level);
+ break;
+ case SEC_ASN1_GENERALIZED_TIME:
+ SECU_PrintGeneralizedTime(out, i, m, level);
+ break;
+ case SEC_ASN1_UTC_TIME:
+ SECU_PrintUTCTime(out, i, m, level);
+ break;
+ case SEC_ASN1_NULL:
+ SECU_Indent(out, level); fprintf(out, "%s: NULL\n", m);
+ break;
+ case SEC_ASN1_SET:
+ case SEC_ASN1_SEQUENCE:
+ SECU_PrintSet(out, i, m, level);
+ break;
+
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+}
+
+static void
+secu_PrintAny(FILE *out, SECItem *i, char *m, int level)
+{
+ if ( i->len ) {
+ switch (i->data[0] & SEC_ASN1_CLASS_MASK) {
+ case SEC_ASN1_CONTEXT_SPECIFIC:
+ secu_PrintContextSpecific(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL:
+ secu_PrintUniversal(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+ }
+}
+
+static int
+secu_PrintValidity(FILE *out, CERTValidity *v, char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintUTCTime(out, &v->notBefore, "Not Before", level+1);
+ SECU_PrintUTCTime(out, &v->notAfter, "Not After", level+1);
+ return 0;
+}
+
+void
+SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level)
+{
+ const char *name;
+ SECOidData *oiddata;
+
+ oiddata = SECOID_FindOID(oid);
+ if (oiddata == NULL) {
+ SECU_PrintAsHex(out, oid, m, level);
+ return;
+ }
+ name = oiddata->desc;
+
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", name);
+}
+
+void
+SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level)
+{
+ SECU_PrintObjectID(out, &a->algorithm, m, level);
+
+ if (a->parameters.len == 0
+ || (a->parameters.len == 2
+ && PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) {
+ /* No arguments or NULL argument */
+ } else {
+ /* Print args to algorithm */
+ SECU_PrintAsHex(out, &a->parameters, "Args", level+1);
+ }
+}
+
+static void
+secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level)
+{
+ SECItem *value;
+ int i;
+ char om[100];
+
+ if (m) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ }
+
+ /*
+ * Should make this smarter; look at the type field and then decode
+ * and print the value(s) appropriately!
+ */
+ SECU_PrintObjectID(out, &(attr->type), "Type", level+1);
+ if (attr->values != NULL) {
+ i = 0;
+ while ((value = attr->values[i++]) != NULL) {
+ sprintf(om, "Value (%d)%s", i, attr->encoded ? " (encoded)" : "");
+ if (attr->encoded || attr->typeTag == NULL) {
+ SECU_PrintAsHex(out, value, om, level+1);
+ } else {
+ switch (attr->typeTag->offset) {
+ default:
+ SECU_PrintAsHex(out, value, om, level+1);
+ break;
+ case SEC_OID_PKCS9_CONTENT_TYPE:
+ SECU_PrintObjectID(out, value, om, level+1);
+ break;
+ case SEC_OID_PKCS9_SIGNING_TIME:
+ SECU_PrintUTCTime(out, value, om, level+1);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void
+secu_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+#if 0 /*
+ * um, yeah, that might be nice, but if you look at the callers
+ * you will see that they do not *set* this, so this will not work!
+ * Instead, somebody needs to fix the callers to be smarter about
+ * public key stuff, if that is important.
+ */
+ PORT_Assert(pk->keyType == rsaKey);
+#endif
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level+1);
+ SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level+1);
+}
+
+static void
+secu_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level+1);
+}
+
+static int
+secu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena,
+ CERTSubjectPublicKeyInfo *i, char *msg, int level)
+{
+ SECKEYPublicKey *pk;
+ int rv;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", msg);
+ SECU_PrintAlgorithmID(out, &i->algorithm, "Public Key Algorithm", level+1);
+
+ pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey));
+ if (!pk)
+ return PORT_GetError();
+
+ DER_ConvertBitString(&i->subjectPublicKey);
+ switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) {
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ rv = SEC_ASN1DecodeItem(arena, pk,
+ SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate),
+ &i->subjectPublicKey);
+ if (rv)
+ return rv;
+ secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1);
+ break;
+ case SEC_OID_ANSIX9_DSA_SIGNATURE:
+ rv = SEC_ASN1DecodeItem(arena, pk,
+ SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate),
+ &i->subjectPublicKey);
+ if (rv)
+ return rv;
+ secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1);
+ break;
+ default:
+ fprintf(out, "bad SPKI algorithm type\n");
+ return 0;
+ }
+
+ return 0;
+}
+
+static SECStatus
+secu_PrintX509InvalidDate(FILE *out, SECItem *value, char *msg, int level)
+{
+ SECItem decodedValue;
+ SECStatus rv;
+ int64 invalidTime;
+ char *formattedTime = NULL;
+
+ decodedValue.data = NULL;
+ rv = SEC_ASN1DecodeItem (NULL, &decodedValue,
+ SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
+ value);
+ if (rv == SECSuccess) {
+ rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
+ if (rv == SECSuccess) {
+ formattedTime = CERT_GenTime2FormattedAscii
+ (invalidTime, "%a %b %d %H:%M:%S %Y");
+ SECU_Indent(out, level +1);
+ fprintf (out, "%s: %s\n", msg, formattedTime);
+ PORT_Free (formattedTime);
+ }
+ }
+ PORT_Free (decodedValue.data);
+ return (rv);
+}
+
+static SECStatus
+PrintExtKeyUsageExten (FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTOidSequence *os;
+ SECItem **op;
+
+ SECU_Indent(out, level); fprintf(out, "Extended Key Usage Extension:\n");
+
+ os = CERT_DecodeOidSequence(value);
+ if( (CERTOidSequence *)NULL == os ) {
+ return SECFailure;
+ }
+
+ for( op = os->oids; *op; op++ ) {
+ SECOidData *od = SECOID_FindOID(*op);
+
+ if( (SECOidData *)NULL == od ) {
+ SECU_Indent(out, level+1);
+ SECU_PrintAsHex(out, *op, "Unknown:", level+2);
+ secu_Newline(out);
+ continue;
+ }
+
+ SECU_Indent(out, level+1);
+ if( od->desc ) fprintf(out, "%s", od->desc);
+ else SECU_PrintAsHex(out, &od->oid, "", level+2);
+
+ secu_Newline(out);
+ }
+
+ return SECSuccess;
+}
+
+char *
+itemToString(SECItem *item)
+{
+ char *string;
+
+ string = PORT_ZAlloc(item->len+1);
+ if (string == NULL) return NULL;
+ PORT_Memcpy(string,item->data,item->len);
+ string[item->len] = 0;
+ return string;
+}
+
+static SECStatus
+secu_PrintPolicyQualifier(FILE *out,CERTPolicyQualifier *policyQualifier,char *msg,int level)
+{
+ CERTUserNotice *userNotice;
+ SECItem **itemList = NULL;
+ char *string;
+
+ SECU_PrintObjectID(out, &policyQualifier->qualifierID ,
+ "Policy Qualifier Name", level);
+
+ switch (policyQualifier->oid) {
+ case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
+ userNotice = CERT_DecodeUserNotice(&policyQualifier->qualifierValue);
+ if (userNotice) {
+ if (userNotice->noticeReference.organization.len != 0) {
+ string=itemToString(&userNotice->noticeReference.organization);
+ itemList = userNotice->noticeReference.noticeNumbers;
+ while (*itemList) {
+ SECU_PrintInteger(out,*itemList,string,level+1);
+ itemList++;
+ }
+ PORT_Free(string);
+ }
+ if (userNotice->displayText.len != 0) {
+ SECU_PrintString(out,&userNotice->displayText,
+ "Display Text", level+1);
+ }
+ break;
+ }
+ /* fall through on error */
+ case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
+ default:
+ secu_PrintAny(out, &policyQualifier->qualifierValue, "Policy Qualifier Data", level+1);
+ break;
+ }
+
+ return SECSuccess;
+
+}
+
+static SECStatus
+secu_PrintPolicyInfo(FILE *out,CERTPolicyInfo *policyInfo,char *msg,int level)
+{
+ CERTPolicyQualifier **policyQualifiers;
+
+ policyQualifiers = policyInfo->policyQualifiers;
+ SECU_PrintObjectID(out, &policyInfo->policyID , "Policy Name", level);
+
+ while (*policyQualifiers != NULL) {
+ secu_PrintPolicyQualifier(out,*policyQualifiers,"",level+1);
+ policyQualifiers++;
+ }
+ return SECSuccess;
+
+}
+
+static SECStatus
+secu_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTCertificatePolicies *policies = NULL;
+ CERTPolicyInfo **policyInfos;
+
+ if (msg) {
+ SECU_Indent(out, level);
+ fprintf(out,"%s: \n",msg);
+ level++;
+ }
+ policies = CERT_DecodeCertificatePoliciesExtension(value);
+ if (policies == NULL) {
+ SECU_PrintAsHex(out, value, "Invalid Policy Data", level);
+ return SECFailure;
+ }
+
+ policyInfos = policies->policyInfos;
+ while (*policyInfos != NULL) {
+ secu_PrintPolicyInfo(out,*policyInfos,"",level);
+ policyInfos++;
+ }
+
+ CERT_DestroyCertificatePoliciesExtension(policies);
+ return SECSuccess;
+}
+
+char *nsTypeBits[] = {
+"SSL Client","SSL Server","S/MIME","Object Signing","Reserved","SSL CA","S/MIME CA","ObjectSigning CA" };
+
+static SECStatus
+secu_PrintBasicConstraints(FILE *out, SECItem *value, char *msg, int level) {
+ CERTBasicConstraints constraints;
+ SECStatus rv;
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out,"%s: ",msg);
+ }
+ rv = CERT_DecodeBasicConstraintValue(&constraints,value);
+ if (rv == SECSuccess && constraints.isCA) {
+ fprintf(out,"Is a CA with a maximum path length of %d.\n",
+ constraints.pathLenConstraint);
+ } else {
+ fprintf(out,"Is not a CA.\n");
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintNSCertType(FILE *out, SECItem *value, char *msg, int level) {
+ char NS_Type=0;
+ int len, i, found=0;
+
+ if (value->data[1] & 0x80) {
+ len = 3;
+ } else {
+ len = value->data[1];
+ }
+ if ((value->data[0] != SEC_ASN1_BIT_STRING) || (len < 2)) {
+ secu_PrintAny(out, value, "Data", level);
+ return SECSuccess;
+ }
+ NS_Type=value->data[3];
+
+
+ if (msg) {
+ SECU_Indent(out, level);
+ fprintf(out,"%s: ",msg);
+ } else {
+ SECU_Indent(out, level);
+ fprintf(out,"Netscape Certificate Type: ");
+ }
+ for (i=0; i < 8; i++) {
+ if ( (0x80 >> i) & NS_Type) {
+ fprintf(out,"%c%s",found?',':'<',nsTypeBits[i]);
+ found = 1;
+ }
+ }
+ if (found) { fprintf(out,">\n"); } else { fprintf(out,"none\n"); }
+ return SECSuccess;
+}
+
+void
+SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ char *msg, int level)
+{
+ SECOidTag oidTag;
+
+ if ( extensions ) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", msg);
+
+ while ( *extensions ) {
+ SECItem *tmpitem;
+ SECU_Indent(out, level+1); fprintf(out, "Name:\n");
+
+ tmpitem = &(*extensions)->id;
+ SECU_PrintObjectID(out, tmpitem, NULL, level+2);
+
+ tmpitem = &(*extensions)->critical;
+ if ( tmpitem->len ) {
+ secu_PrintBoolean(out, tmpitem, "Critical", level+1);
+ }
+
+ oidTag = SECOID_FindOIDTag (&((*extensions)->id));
+ tmpitem = &((*extensions)->value);
+
+ switch (oidTag) {
+ case SEC_OID_X509_INVALID_DATE:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME:
+ secu_PrintX509InvalidDate(out, tmpitem, "Date", level + 1);
+ break;
+ case SEC_OID_X509_CERTIFICATE_POLICIES:
+ secu_PrintPolicy(out, tmpitem, "Data", level +1);
+ break;
+ case SEC_OID_NS_CERT_EXT_BASE_URL:
+ case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CRL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CERT_URL:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
+ case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL:
+ case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
+ case SEC_OID_OCSP_RESPONDER:
+ SECU_PrintString(out,tmpitem, "URL", level+1);
+ break;
+ case SEC_OID_NS_CERT_EXT_COMMENT:
+ SECU_PrintString(out,tmpitem, "Comment", level+1);
+ break;
+ case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
+ SECU_PrintString(out,tmpitem, "ServerName", level+1);
+ break;
+ case SEC_OID_NS_CERT_EXT_CERT_TYPE:
+ secu_PrintNSCertType(out,tmpitem,"Data",level+1);
+ break;
+ case SEC_OID_X509_BASIC_CONSTRAINTS:
+ secu_PrintBasicConstraints(out,tmpitem,"Data",level+1);
+ break;
+ case SEC_OID_X509_SUBJECT_ALT_NAME:
+ case SEC_OID_X509_ISSUER_ALT_NAME:
+ /*
+ * We should add at least some of the more interesting cases
+ * here, but need to have subroutines to back them up.
+ */
+ case SEC_OID_NS_CERT_EXT_NETSCAPE_OK:
+ case SEC_OID_NS_CERT_EXT_ISSUER_LOGO:
+ case SEC_OID_NS_CERT_EXT_SUBJECT_LOGO:
+ case SEC_OID_NS_CERT_EXT_ENTITY_LOGO:
+ case SEC_OID_NS_CERT_EXT_USER_PICTURE:
+ case SEC_OID_NS_KEY_USAGE_GOVT_APPROVED:
+
+ /* x.509 v3 Extensions */
+ case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
+ case SEC_OID_X509_SUBJECT_KEY_ID:
+ case SEC_OID_X509_KEY_USAGE:
+ case SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD:
+ case SEC_OID_X509_NAME_CONSTRAINTS:
+ case SEC_OID_X509_CRL_DIST_POINTS:
+ case SEC_OID_X509_POLICY_MAPPINGS:
+ case SEC_OID_X509_POLICY_CONSTRAINTS:
+ case SEC_OID_X509_AUTH_KEY_ID:
+ goto defualt;
+ case SEC_OID_X509_EXT_KEY_USAGE:
+ PrintExtKeyUsageExten(out, tmpitem, "", level+1);
+ break;
+ case SEC_OID_X509_AUTH_INFO_ACCESS:
+
+ case SEC_OID_X509_CRL_NUMBER:
+ case SEC_OID_X509_REASON_CODE:
+
+ /* PKIX OIDs */
+ case SEC_OID_PKIX_OCSP:
+ case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NONCE:
+ case SEC_OID_PKIX_OCSP_CRL:
+ case SEC_OID_PKIX_OCSP_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NO_CHECK:
+ case SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF:
+ case SEC_OID_PKIX_OCSP_SERVICE_LOCATOR:
+ case SEC_OID_PKIX_REGCTRL_REGTOKEN:
+ case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
+ case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
+ case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
+ case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
+ case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
+ case SEC_OID_PKIX_REGINFO_UTF8_PAIRS:
+ case SEC_OID_PKIX_REGINFO_CERT_REQUEST:
+ case SEC_OID_EXT_KEY_USAGE_SERVER_AUTH:
+ case SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH:
+ case SEC_OID_EXT_KEY_USAGE_CODE_SIGN:
+ case SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT:
+ case SEC_OID_EXT_KEY_USAGE_TIME_STAMP:
+
+ default:
+ defualt:
+ /*SECU_PrintAsHex(out, tmpitem, "Data", level+1); */
+ secu_PrintAny(out, tmpitem, "Data", level+1);
+ break;
+ }
+
+ secu_Newline(out);
+ extensions++;
+ }
+ }
+}
+
+
+void
+SECU_PrintName(FILE *out, CERTName *name, char *msg, int level)
+{
+ char *str;
+
+ SECU_Indent(out, level); fprintf(out, "%s: ", msg);
+
+ str = CERT_NameToAscii(name);
+ if (!str)
+ str = "!Invalid AVA!";
+ fprintf(out, str);
+
+ secu_Newline(out);
+}
+
+void
+printflags(char *trusts, unsigned int flags)
+{
+ if (flags & CERTDB_VALID_CA)
+ if (!(flags & CERTDB_TRUSTED_CA) &&
+ !(flags & CERTDB_TRUSTED_CLIENT_CA))
+ PORT_Strcat(trusts, "c");
+ if (flags & CERTDB_VALID_PEER)
+ if (!(flags & CERTDB_TRUSTED))
+ PORT_Strcat(trusts, "p");
+ if (flags & CERTDB_TRUSTED_CA)
+ PORT_Strcat(trusts, "C");
+ if (flags & CERTDB_TRUSTED_CLIENT_CA)
+ PORT_Strcat(trusts, "T");
+ if (flags & CERTDB_TRUSTED)
+ PORT_Strcat(trusts, "P");
+ if (flags & CERTDB_USER)
+ PORT_Strcat(trusts, "u");
+ if (flags & CERTDB_SEND_WARN)
+ PORT_Strcat(trusts, "w");
+ if (flags & CERTDB_INVISIBLE_CA)
+ PORT_Strcat(trusts, "I");
+ if (flags & CERTDB_GOVT_APPROVED_CA)
+ PORT_Strcat(trusts, "G");
+ return;
+}
+
+/* callback for listing certs through pkcs11 */
+SECStatus
+SECU_PrintCertNickname(CERTCertificate *cert, void *data)
+{
+ CERTCertTrust *trust;
+ FILE *out;
+ char trusts[30];
+ char *name;
+
+ PORT_Memset (trusts, 0, sizeof (trusts));
+ out = (FILE *)data;
+
+ name = cert->nickname;
+ if ( name == NULL ) {
+ name = cert->emailAddr;
+ }
+ if ( name == NULL ) {
+ name = "(NULL)";
+ }
+
+ trust = cert->trust;
+ if (trust) {
+ printflags(trusts, trust->sslFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust->emailFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust->objectSigningFlags);
+ } else {
+ PORT_Memcpy(trusts,",,",3);
+ }
+ fprintf(out, "%-60s %-5s\n", name, trusts);
+
+ return (SECSuccess);
+}
+
+int
+SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = NULL;
+ CERTCertificateRequest *cr;
+ int rv;
+
+ /* Decode certificate request */
+ cr = (CERTCertificateRequest*) PORT_ZAlloc(sizeof(CERTCertificateRequest));
+ if (!cr)
+ return PORT_GetError();
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_ASN1DecodeItem(arena, cr,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), der);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &cr->version, "Version", level+1);
+ SECU_PrintName(out, &cr->subject, "Subject", level+1);
+ rv = secu_PrintSubjectPublicKeyInfo(out, arena, &cr->subjectPublicKeyInfo,
+ "Subject Public Key Info", level+1);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+ secu_PrintAny(out, cr->attributes[0], "Attributes", level+1);
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return 0;
+}
+
+int
+SECU_PrintCertificate(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = NULL;
+ CERTCertificate *c;
+ int rv;
+ int iv;
+
+ /* Decode certificate */
+ c = (CERTCertificate*) PORT_ZAlloc(sizeof(CERTCertificate));
+ if (!c)
+ return PORT_GetError();
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_ASN1DecodeItem(arena, c,
+ SEC_ASN1_GET(CERT_CertificateTemplate), der);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ iv = DER_GetInteger(&c->version);
+ SECU_Indent(out, level+1); fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+
+ SECU_PrintInteger(out, &c->serialNumber, "Serial Number", level+1);
+ SECU_PrintAlgorithmID(out, &c->signature, "Signature Algorithm", level+1);
+ SECU_PrintName(out, &c->issuer, "Issuer", level+1);
+ secu_PrintValidity(out, &c->validity, "Validity", level+1);
+ SECU_PrintName(out, &c->subject, "Subject", level+1);
+ rv = secu_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo,
+ "Subject Public Key Info", level+1);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+ SECU_PrintExtensions(out, c->extensions, "Signed Extensions", level+1);
+
+ SECU_PrintFingerprints(out, &c->derCert, "Fingerprint", level);
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return 0;
+}
+
+int
+SECU_PrintPublicKey(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = NULL;
+ SECKEYPublicKey key;
+ int rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), der);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+
+ /* Pretty print it out */
+ secu_PrintRSAPublicKey(out, &key, m, level);
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return 0;
+}
+
+#ifdef HAVE_EPV_TEMPLATE
+int
+SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = NULL;
+ SECKEYEncryptedPrivateKeyInfo key;
+ int rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), der);
+ if (rv) {
+ PORT_FreeArena(arena, PR_TRUE);
+ return rv;
+ }
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintAlgorithmID(out, &key.algorithm, "Encryption Algorithm",
+ level+1);
+ SECU_PrintAsHex(out, &key.encryptedData, "Encrypted Data", level+1);
+
+ PORT_FreeArena(arena, PR_TRUE);
+ return 0;
+}
+#endif
+
+int
+SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
+{
+ unsigned char fingerprint[20];
+ char *fpStr = NULL;
+ SECItem fpItem;
+ /* print MD5 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = MD5_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level); fprintf(out, "%s (MD5):\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fpStr = NULL;
+ /* print SHA1 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ PK11_HashBuf(SEC_OID_SHA1,fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = SHA1_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level); fprintf(out, "%s (SHA1):\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fprintf(out, "\n");
+ return 0;
+}
+
+/*
+** PKCS7 Support
+*/
+
+/* forward declaration */
+static int
+secu_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *, int);
+
+/*
+** secu_PrintPKCS7EncContent
+** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
+*/
+static void
+secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src,
+ char *m, int level)
+{
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Content Type: %s\n",
+ (src->contentTypeTag != NULL) ? src->contentTypeTag->desc
+ : "Unknown");
+ SECU_PrintAlgorithmID(out, &(src->contentEncAlg),
+ "Content Encryption Algorithm", level+1);
+ SECU_PrintAsHex(out, &(src->encContent),
+ "Encrypted Content", level+1);
+}
+
+/*
+** secu_PrintRecipientInfo
+** Prints a PKCS7RecipientInfo type
+*/
+static void
+secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m,
+ int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ /* Parse and display encrypted key */
+ SECU_PrintAlgorithmID(out, &(info->keyEncAlg),
+ "Key Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
+}
+
+/*
+** secu_PrintSignerInfo
+** Prints a PKCS7SingerInfo type
+*/
+static void
+secu_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m, int level)
+{
+ SEC_PKCS7Attribute *attr;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ SECU_PrintAlgorithmID(out, &(info->digestAlg), "Digest Algorithm",
+ level + 1);
+
+ if (info->authAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Authenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->authAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%d)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+
+ /* Parse and display signature */
+ SECU_PrintAlgorithmID(out, &(info->digestEncAlg),
+ "Digest Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encDigest), "Encrypted Digest", level + 1);
+
+ if (info->unAuthAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Unauthenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->unAuthAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%x)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+}
+
+void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level)
+{
+ CERTCrlEntry *entry;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintAlgorithmID(out, &(crl->signatureAlg), "Signature Algorithm",
+ level + 1);
+ SECU_PrintName(out, &(crl->name), "Name", level + 1);
+ SECU_PrintUTCTime(out, &(crl->lastUpdate), "Last Update", level + 1);
+ SECU_PrintUTCTime(out, &(crl->nextUpdate), "Next Update", level + 1);
+
+ if (crl->entries != NULL) {
+ iv = 0;
+ while ((entry = crl->entries[iv++]) != NULL) {
+ sprintf(om, "Entry (%x):\n", iv);
+ SECU_Indent(out, level + 1); fprintf(out, om);
+ SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
+ level + 2);
+ SECU_PrintUTCTime(out, &(entry->revocationDate), "Revocation Date",
+ level + 2);
+ SECU_PrintExtensions
+ (out, entry->extensions, "Signed CRL Entries Extensions", level + 1);
+ }
+ }
+ SECU_PrintExtensions
+ (out, crl->extensions, "Signed CRL Extension", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Signed
+** Pretty print a PKCS7 signed data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src, char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* digest algorithms */
+ SECItem *aCert; /* certificate */
+ CERTSignedCrl *aCrl; /* certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* signer information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ /* Now for the content */
+ rv = secu_PrintPKCS7ContentInfo(out, &(src->contentInfo),
+ "Content Information", level + 1);
+ if (rv != 0)
+ return rv;
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2); fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level+3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level+3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+/*
+** secu_PrintPKCS7Enveloped
+** Pretty print a PKCS7 enveloped data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
+ char *m, int level)
+{
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7SignedEnveloped
+** Pretty print a PKCS7 singed and enveloped data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7SignedAndEnveloped(FILE *out,
+ SEC_PKCS7SignedAndEnvelopedData *src,
+ char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* pointer for digest algorithms */
+ SECItem *aCert; /* pointer for certificate */
+ CERTSignedCrl *aCrl; /* pointer for certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2); fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level+3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level+3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+int
+SECU_PrintCrl (FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = NULL;
+ CERTCrl *c = NULL;
+ int rv;
+
+ do {
+ /* Decode CRL */
+ c = (CERTCrl*) PORT_ZAlloc(sizeof(CERTCrl));
+ if (!c) {
+ rv = PORT_GetError();
+ break;
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ rv = SEC_ERROR_NO_MEMORY;
+ break;
+ }
+
+ rv = SEC_ASN1DecodeItem(arena, c, SEC_ASN1_GET(CERT_CrlTemplate), der);
+ if (rv != SECSuccess)
+ break;
+ SECU_PrintCRLInfo (out, c, m, level);
+ } while (0);
+ PORT_FreeArena (arena, PR_FALSE);
+ PORT_Free (c);
+ return (rv);
+}
+
+
+/*
+** secu_PrintPKCS7Encrypted
+** Pretty print a PKCS7 encrypted data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
+ char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Digested
+** Pretty print a PKCS7 digested data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src,
+ char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ SECU_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm",
+ level + 1);
+ secu_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
+ level + 1);
+ SECU_PrintAsHex(out, &src->digest, "Digest", level + 1);
+}
+
+/*
+** secu_PrintPKCS7ContentInfo
+** Takes a SEC_PKCS7ContentInfo type and sends the contents to the
+** appropriate function
+*/
+static int
+secu_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src,
+ char *m, int level)
+{
+ char *desc;
+ SECOidTag kind;
+ int rv;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
+
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ if (src->contentTypeTag == NULL) {
+ desc = "Unknown";
+ kind = SEC_OID_PKCS7_DATA;
+ } else {
+ desc = src->contentTypeTag->desc;
+ kind = src->contentTypeTag->offset;
+ }
+
+ if (src->content.data == NULL) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", desc);
+ level++;
+ SECU_Indent(out, level); fprintf(out, "<no content>\n");
+ return 0;
+ }
+
+ rv = 0;
+ switch (kind) {
+ case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */
+ rv = secu_PrintPKCS7Signed(out, src->content.signedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */
+ secu_PrintPKCS7Enveloped(out, src->content.envelopedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */
+ rv = secu_PrintPKCS7SignedAndEnveloped(out,
+ src->content.signedAndEnvelopedData,
+ desc, level);
+ break;
+
+ case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */
+ secu_PrintPKCS7Digested(out, src->content.digestedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */
+ secu_PrintPKCS7Encrypted(out, src->content.encryptedData, desc, level);
+ break;
+
+ default:
+ SECU_PrintAsHex(out, src->content.data, desc, level);
+ break;
+ }
+
+ return rv;
+}
+
+/*
+** SECU_PrintPKCS7ContentInfo
+** Decode and print any major PKCS7 data type (up to version 1).
+*/
+int
+SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m, int level)
+{
+ SEC_PKCS7ContentInfo *cinfo;
+ int rv;
+
+ cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (cinfo != NULL) {
+ /* Send it to recursive parsing and printing module */
+ rv = secu_PrintPKCS7ContentInfo(out, cinfo, m, level);
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ } else {
+ rv = -1;
+ }
+
+ return rv;
+}
+
+/*
+** End of PKCS7 functions
+*/
+
+void
+printFlags(FILE *out, unsigned int flags, int level)
+{
+ if ( flags & CERTDB_VALID_PEER ) {
+ SECU_Indent(out, level); fprintf(out, "Valid Peer\n");
+ }
+ if ( flags & CERTDB_TRUSTED ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted\n");
+ }
+ if ( flags & CERTDB_SEND_WARN ) {
+ SECU_Indent(out, level); fprintf(out, "Warn When Sending\n");
+ }
+ if ( flags & CERTDB_VALID_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Valid CA\n");
+ }
+ if ( flags & CERTDB_TRUSTED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted CA\n");
+ }
+ if ( flags & CERTDB_NS_TRUSTED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Netscape Trusted CA\n");
+ }
+ if ( flags & CERTDB_USER ) {
+ SECU_Indent(out, level); fprintf(out, "User\n");
+ }
+ if ( flags & CERTDB_TRUSTED_CLIENT_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted Client CA\n");
+ }
+#ifdef DEBUG
+ if ( flags & CERTDB_GOVT_APPROVED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Step-up\n");
+ }
+#endif /* DEBUG */
+}
+
+void
+SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "SSL Flags:\n");
+ printFlags(out, trust->sslFlags, level+2);
+ SECU_Indent(out, level+1); fprintf(out, "Email Flags:\n");
+ printFlags(out, trust->emailFlags, level+2);
+ SECU_Indent(out, level+1); fprintf(out, "Object Signing Flags:\n");
+ printFlags(out, trust->objectSigningFlags, level+2);
+}
+
+int SECU_PrintSignedData(FILE *out, SECItem *der, char *m,
+ int level, SECU_PPFunc inner)
+{
+ PRArenaPool *arena = NULL;
+ CERTSignedData *sd;
+ int rv;
+
+ /* Strip off the signature */
+ sd = (CERTSignedData*) PORT_ZAlloc(sizeof(CERTSignedData));
+ if (!sd)
+ return PORT_GetError();
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate),
+ der);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ rv = (*inner)(out, &sd->data, "Data", level+1);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+ }
+
+ SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm",
+ level+1);
+ DER_ConvertBitString(&sd->signature);
+ SECU_PrintAsHex(out, &sd->signature, "Signature", level+1);
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return 0;
+
+}
+
+
+#ifdef AIX
+int _OS_SELECT (int nfds, void *readfds, void *writefds,
+ void *exceptfds, struct timeval *timeout) {
+ return select (nfds,readfds,writefds,exceptfds,timeout);
+}
+#endif
+
+SECItem *
+SECU_GetPBEPassword(void *arg)
+{
+ char *p = NULL;
+ SECItem *pwitem = NULL;
+
+ p = SECU_GetPasswordString(arg,"Password: ");
+
+ /* NOTE: This function is obviously unfinished. */
+
+ if ( pwitem == NULL ) {
+ fprintf(stderr, "Error hashing password\n");
+ return NULL;
+ }
+
+ return pwitem;
+}
+
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd)
+{
+ PRBool found;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char *optstring;
+ int i, j;
+
+ optstring = (char *)malloc(cmd->numCommands + 2*cmd->numOptions);
+ j = 0;
+
+ for (i=0; i<cmd->numCommands; i++) {
+ optstring[j++] = cmd->commands[i].flag;
+ }
+ for (i=0; i<cmd->numOptions; i++) {
+ optstring[j++] = cmd->options[i].flag;
+ if (cmd->options[i].needsArg)
+ optstring[j++] = ':';
+ }
+ optstring[j] = '\0';
+ optstate = PL_CreateOptState(argc, argv, optstring);
+
+ /* Parse command line arguments */
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+
+ /* Wasn't really an option, just standalone arg. */
+ if (optstate->option == '\0')
+ continue;
+
+ found = PR_FALSE;
+
+ for (i=0; i<cmd->numCommands; i++) {
+ if (cmd->commands[i].flag == optstate->option) {
+ cmd->commands[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->commands[i].arg = (char *)optstate->value;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ for (i=0; i<cmd->numOptions; i++) {
+ if (cmd->options[i].flag == optstate->option) {
+ cmd->options[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->options[i].arg = (char *)optstate->value;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return SECFailure;
+ }
+ if (status == PL_OPT_BAD)
+ return SECFailure;
+ return SECSuccess;
+}
+
+char *
+SECU_GetOptionArg(secuCommand *cmd, int optionNum)
+{
+ if (optionNum < 0 || optionNum >= cmd->numOptions)
+ return NULL;
+ if (cmd->options[optionNum].activated)
+ return PL_strdup(cmd->options[optionNum].arg);
+ else
+ return NULL;
+}
+
+static char SECUErrorBuf[64];
+
+char *
+SECU_ErrorStringRaw(int16 err)
+{
+ if (err == 0)
+ sprintf(SECUErrorBuf, "");
+ else if (err == SEC_ERROR_BAD_DATA)
+ sprintf(SECUErrorBuf, "Bad data");
+ else if (err == SEC_ERROR_BAD_DATABASE)
+ sprintf(SECUErrorBuf, "Problem with database");
+ else if (err == SEC_ERROR_BAD_DER)
+ sprintf(SECUErrorBuf, "Problem with DER");
+ else if (err == SEC_ERROR_BAD_KEY)
+ sprintf(SECUErrorBuf, "Problem with key");
+ else if (err == SEC_ERROR_BAD_PASSWORD)
+ sprintf(SECUErrorBuf, "Incorrect password");
+ else if (err == SEC_ERROR_BAD_SIGNATURE)
+ sprintf(SECUErrorBuf, "Bad signature");
+ else if (err == SEC_ERROR_EXPIRED_CERTIFICATE)
+ sprintf(SECUErrorBuf, "Expired certificate");
+ else if (err == SEC_ERROR_EXTENSION_VALUE_INVALID)
+ sprintf(SECUErrorBuf, "Invalid extension value");
+ else if (err == SEC_ERROR_INPUT_LEN)
+ sprintf(SECUErrorBuf, "Problem with input length");
+ else if (err == SEC_ERROR_INVALID_ALGORITHM)
+ sprintf(SECUErrorBuf, "Invalid algorithm");
+ else if (err == SEC_ERROR_INVALID_ARGS)
+ sprintf(SECUErrorBuf, "Invalid arguments");
+ else if (err == SEC_ERROR_INVALID_AVA)
+ sprintf(SECUErrorBuf, "Invalid AVA");
+ else if (err == SEC_ERROR_INVALID_TIME)
+ sprintf(SECUErrorBuf, "Invalid time");
+ else if (err == SEC_ERROR_IO)
+ sprintf(SECUErrorBuf, "Security I/O error");
+ else if (err == SEC_ERROR_LIBRARY_FAILURE)
+ sprintf(SECUErrorBuf, "Library failure");
+ else if (err == SEC_ERROR_NO_MEMORY)
+ sprintf(SECUErrorBuf, "Out of memory");
+ else if (err == SEC_ERROR_OLD_CRL)
+ sprintf(SECUErrorBuf, "CRL is older than the current one");
+ else if (err == SEC_ERROR_OUTPUT_LEN)
+ sprintf(SECUErrorBuf, "Problem with output length");
+ else if (err == SEC_ERROR_UNKNOWN_ISSUER)
+ sprintf(SECUErrorBuf, "Unknown issuer");
+ else if (err == SEC_ERROR_UNTRUSTED_CERT)
+ sprintf(SECUErrorBuf, "Untrusted certificate");
+ else if (err == SEC_ERROR_UNTRUSTED_ISSUER)
+ sprintf(SECUErrorBuf, "Untrusted issuer");
+ else if (err == SSL_ERROR_BAD_CERTIFICATE)
+ sprintf(SECUErrorBuf, "Bad certificate");
+ else if (err == SSL_ERROR_BAD_CLIENT)
+ sprintf(SECUErrorBuf, "Bad client");
+ else if (err == SSL_ERROR_BAD_SERVER)
+ sprintf(SECUErrorBuf, "Bad server");
+ else if (err == SSL_ERROR_EXPORT_ONLY_SERVER)
+ sprintf(SECUErrorBuf, "Export only server");
+ else if (err == SSL_ERROR_NO_CERTIFICATE)
+ sprintf(SECUErrorBuf, "No certificate");
+ else if (err == SSL_ERROR_NO_CYPHER_OVERLAP)
+ sprintf(SECUErrorBuf, "No cypher overlap");
+ else if (err == SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE)
+ sprintf(SECUErrorBuf, "Unsupported certificate type");
+ else if (err == SSL_ERROR_UNSUPPORTED_VERSION)
+ sprintf(SECUErrorBuf, "Unsupported version");
+ else if (err == SSL_ERROR_US_ONLY_SERVER)
+ sprintf(SECUErrorBuf, "U.S. only server");
+ else if (err == PR_IO_ERROR)
+ sprintf(SECUErrorBuf, "I/O error");
+
+ else if (err == SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE)
+ sprintf (SECUErrorBuf, "Expired Issuer Certificate");
+ else if (err == SEC_ERROR_REVOKED_CERTIFICATE)
+ sprintf (SECUErrorBuf, "Revoked certificate");
+ else if (err == SEC_ERROR_NO_KEY)
+ sprintf (SECUErrorBuf, "No private key in database for this cert");
+ else if (err == SEC_ERROR_CERT_NOT_VALID)
+ sprintf (SECUErrorBuf, "Certificate is not valid");
+ else if (err == SEC_ERROR_EXTENSION_NOT_FOUND)
+ sprintf (SECUErrorBuf, "Certificate extension was not found");
+ else if (err == SEC_ERROR_EXTENSION_VALUE_INVALID)
+ sprintf (SECUErrorBuf, "Certificate extension value invalid");
+ else if (err == SEC_ERROR_CA_CERT_INVALID)
+ sprintf (SECUErrorBuf, "Issuer certificate is invalid");
+ else if (err == SEC_ERROR_CERT_USAGES_INVALID)
+ sprintf (SECUErrorBuf, "Certificate usages is invalid");
+ else if (err == SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION)
+ sprintf (SECUErrorBuf, "Certificate has unknown critical extension");
+ else if (err == SEC_ERROR_PKCS7_BAD_SIGNATURE)
+ sprintf (SECUErrorBuf, "Bad PKCS7 signature");
+ else if (err == SEC_ERROR_INADEQUATE_KEY_USAGE)
+ sprintf (SECUErrorBuf, "Certificate not approved for this operation");
+ else if (err == SEC_ERROR_INADEQUATE_CERT_TYPE)
+ sprintf (SECUErrorBuf, "Certificate not approved for this operation");
+
+ return SECUErrorBuf;
+}
+
+char *
+SECU_ErrorString(int16 err)
+{
+ char *error_string;
+
+ *SECUErrorBuf = 0;
+ SECU_ErrorStringRaw (err);
+
+ if (*SECUErrorBuf == 0) {
+ error_string = SECU_GetString(err);
+ if (error_string == NULL || *error_string == '\0')
+ sprintf(SECUErrorBuf, "No error string found for %d.", err);
+ else
+ return error_string;
+ }
+
+ return SECUErrorBuf;
+}
+
+
+void
+SECU_PrintPRandOSError(char *progName)
+{
+ char buffer[513];
+ PRErrorCode err = PR_GetError();
+ PRInt32 errLen = PR_GetErrorTextLength();
+ if (errLen > 0 && errLen < sizeof buffer) {
+ PR_GetErrorText(buffer);
+ }
+ SECU_PrintError(progName, "NSS_Initialize failed");
+ if (errLen > 0 && errLen < sizeof buffer) {
+ PR_fprintf(PR_STDERR, "\t%s\n", buffer);
+ }
+}
diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h
new file mode 100644
index 000000000..e2db2f4c8
--- /dev/null
+++ b/security/nss/cmd/lib/secutil.h
@@ -0,0 +1,327 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#ifndef _SEC_UTIL_H_
+#define _SEC_UTIL_H_
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "prerror.h"
+#include "base64.h"
+#include "key.h"
+#include "secpkcs7.h"
+#include "secasn1.h"
+#include "secder.h"
+#include <stdio.h>
+
+#define SEC_CT_PRIVATE_KEY "private-key"
+#define SEC_CT_PUBLIC_KEY "public-key"
+#define SEC_CT_CERTIFICATE "certificate"
+#define SEC_CT_CERTIFICATE_REQUEST "certificate-request"
+#define SEC_CT_PKCS7 "pkcs7"
+#define SEC_CT_CRL "crl"
+
+#define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
+#define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
+
+#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
+#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
+
+/* From libsec/pcertdb.c --- it's not declared in sec.h */
+extern SECStatus SEC_AddPermCertificate(CERTCertDBHandle *handle,
+ SECItem *derCert, char *nickname, CERTCertTrust *trust);
+
+
+#ifdef SECUTIL_NEW
+typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item,
+ char *msg, int level);
+#else
+typedef int (*SECU_PPFunc)(FILE *out, SECItem *item, char *msg, int level);
+#endif
+
+typedef struct {
+ enum {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2
+ } source;
+ char *data;
+} secuPWData;
+
+/*
+** Change a password on a token, or initialize a token with a password
+** if it does not already have one.
+** Use passwd to send the password in plaintext, pwFile to specify a
+** file containing the password, or NULL for both to prompt the user.
+*/
+SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile);
+
+/* These were stolen from the old sec.h... */
+/*
+** Check a password for legitimacy. Passwords must be at least 8
+** characters long and contain one non-alphabetic. Return DSTrue if the
+** password is ok, DSFalse otherwise.
+*/
+extern PRBool SEC_CheckPassword(char *password);
+
+/*
+** Blind check of a password. Complement to SEC_CheckPassword which
+** ignores length and content type, just retuning DSTrue is the password
+** exists, DSFalse if NULL
+*/
+extern PRBool SEC_BlindCheckPassword(char *password);
+
+/*
+** Get a password.
+** First prompt with "msg" on "out", then read the password from "in".
+** The password is then checked using "chkpw".
+*/
+extern char *SEC_GetPassword(FILE *in, FILE *out, char *msg,
+ PRBool (*chkpw)(char *));
+
+char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+char *SECU_GetPasswordString(void *arg, char *prompt);
+
+/*
+** Write a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to encrypt a password "pw" into a file "fd".
+*/
+extern SECStatus SEC_WriteDongleFile(int fd, char *pw);
+
+/*
+** Get a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to decrypt and return a password from file "fd".
+*/
+extern char *SEC_ReadDongleFile(int fd);
+
+
+/* End stolen headers */
+
+/* Just sticks the two strings together with a / if needed */
+char *SECU_AppendFilenameToDir(char *dir, char *filename);
+
+/* Returns result of getenv("SSL_DIR") or NULL */
+extern char *SECU_DefaultSSLDir(void);
+
+/*
+** Should be called once during initialization to set the default
+** directory for looking for cert.db, key.db, and cert-nameidx.db files
+** Removes trailing '/' in 'base'
+** If 'base' is NULL, defaults to set to .netscape in home directory.
+*/
+extern char *SECU_ConfigDirectory(const char* base);
+
+/*
+** Basic callback function for SSL_GetClientAuthDataHook
+*/
+extern int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey);
+
+/* print out an error message */
+extern void SECU_PrintError(char *progName, char *msg, ...);
+
+/* print out a system error message */
+extern void SECU_PrintSystemError(char *progName, char *msg, ...);
+
+/* Return informative error string */
+extern const char * SECU_Strerror(PRErrorCode errNum);
+
+/* Read the contents of a file into a SECItem */
+extern SECStatus SECU_FileToItem(SECItem *dst, PRFileDesc *src);
+extern SECStatus SECU_TextFileToItem(SECItem *dst, PRFileDesc *src);
+
+/* Read in a DER from a file, may be ascii */
+extern SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii);
+
+/* Indent based on "level" */
+extern void SECU_Indent(FILE *out, int level);
+
+/* Print integer value and hex */
+extern void SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level);
+
+/* Print ObjectIdentifier symbolically */
+extern void SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level);
+
+/* Print AlgorithmIdentifier symbolically */
+extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m,
+ int level);
+
+/* Print SECItem as hex */
+extern void SECU_PrintAsHex(FILE *out, SECItem *i, char *m, int level);
+
+/* dump a buffer in hex and ASCII */
+extern void SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len);
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintUTCTime(FILE *out, SECItem *t, char *m, int level);
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintGeneralizedTime(FILE *out, SECItem *t, char *m,
+ int level);
+
+/* callback for listing certs through pkcs11 */
+extern SECStatus SECU_PrintCertNickname(CERTCertificate *cert, void *data);
+
+/* Dump all certificate nicknames in a database */
+extern SECStatus
+SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc* out,
+ PRBool sortByName, PRBool sortByTrust);
+
+/* See if nickname already in database. Return 1 true, 0 false, -1 error */
+int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname);
+
+/* Dump contents of cert req */
+extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Dump contents of certificate */
+extern int SECU_PrintCertificate(FILE *out, SECItem *der, char *m, int level);
+
+/* print trust flags on a cert */
+extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, int level);
+
+/* Dump contents of public key */
+extern int SECU_PrintPublicKey(FILE *out, SECItem *der, char *m, int level);
+
+#ifdef HAVE_EPV_TEMPLATE
+/* Dump contents of private key */
+extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
+#endif
+
+/* Print the MD5 and SHA1 fingerprints of a cert */
+extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m,
+ int level);
+
+/* Pretty-print any PKCS7 thing */
+extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Init PKCS11 stuff */
+extern SECStatus SECU_PKCS11Init(PRBool readOnly);
+
+/* Dump contents of signed data */
+extern int SECU_PrintSignedData(FILE *out, SECItem *der, char *m, int level,
+ SECU_PPFunc inner);
+
+extern int SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level);
+
+extern void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level);
+
+extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ char *msg, int level);
+
+extern void SECU_PrintName(FILE *out, CERTName *name, char *msg, int level);
+
+#ifdef SECU_GetPassword
+/* Convert a High public Key to a Low public Key */
+extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
+#endif
+
+extern SECItem *SECU_GetPBEPassword(void *arg);
+
+extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+extern SECStatus DER_PrettyPrint(FILE *out, SECItem *it, PRBool raw);
+extern void SEC_Init(void);
+
+extern char *SECU_SECModDBName(void);
+
+extern void SECU_PrintPRandOSError(char *progName);
+
+/*
+ *
+ * Utilities for parsing security tools command lines
+ *
+ */
+
+/* A single command flag */
+typedef struct {
+ char flag;
+ PRBool needsArg;
+ char *arg;
+ PRBool activated;
+} secuCommandFlag;
+
+/* A full array of command/option flags */
+typedef struct
+{
+ int numCommands;
+ int numOptions;
+
+ secuCommandFlag *commands;
+ secuCommandFlag *options;
+} secuCommand;
+
+/* fill the "arg" and "activated" fields for each flag */
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd);
+char *
+SECU_GetOptionArg(secuCommand *cmd, int optionNum);
+
+/*
+ *
+ * Error messaging
+ *
+ */
+
+/* Return informative error string */
+char *SECU_ErrorString(int16 err);
+
+/* Return informative error string. Does not call XP_GetString */
+char *SECU_ErrorStringRaw(int16 err);
+
+void printflags(char *trusts, unsigned int flags);
+
+#ifndef XP_UNIX
+extern int ffs(unsigned int i);
+#endif
+
+#include "secerr.h"
+#include "sslerr.h"
+
+#endif /* _SEC_UTIL_H_ */
diff --git a/security/nss/cmd/lib/sslstubs.c b/security/nss/cmd/lib/sslstubs.c
new file mode 100644
index 000000000..a7ceda64a
--- /dev/null
+++ b/security/nss/cmd/lib/sslstubs.c
@@ -0,0 +1,74 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secport.h" /* for UUID */
+#ifdef XP_WIN
+#include <IO.H>
+#endif
+
+#ifndef NOT_NULL
+char *NOT_NULL(const char *x)
+{
+ return((char *) x);
+}
+#endif
+
+/* Override the macro definition in xpassert.h if necessary. */
+#ifdef XP_AssertAtLine
+#undef XP_AssertAtLine
+#endif
+
+void XP_AssertAtLine(char *pFileName, int iLine)
+{
+ abort();
+}
+
+void FE_Trace(const char *msg)
+{
+ fputs(msg, stderr);
+}
+
+#ifdef XP_WIN
+RPC_STATUS __stdcall UuidCreate(UUID *Uuid)
+{
+ return 0;
+}
+
+void FEU_StayingAlive(void)
+{
+}
+
+int dupsocket(int sock)
+{
+ return dup(sock);
+}
+#endif
diff --git a/security/nss/cmd/lib/strerror.c b/security/nss/cmd/lib/strerror.c
new file mode 100644
index 000000000..32af63603
--- /dev/null
+++ b/security/nss/cmd/lib/strerror.c
@@ -0,0 +1,127 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secutil.h"
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#endif
+
+#if defined(XP_WIN)
+#include <errno.h>
+#include <winsock.h>
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+static char *(mcom_include_merrors_i_strings)(int16 i) ;
+static char *(mcom_include_secerr_i_strings)(int16 i) ;
+static char *(mcom_include_sslerr_i_strings)(int16 i) ;
+static char *(mcom_include_xp_error_i_strings)(int16 i) ;
+static char *(mcom_include_xp_msg_i_strings)(int16 i) ;
+
+
+#ifdef XP_WIN
+
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define EINPROGRESS WSAEINPROGRESS
+#define EALREADY WSAEALREADY
+#define ENOTSOCK WSAENOTSOCK
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#define EMSGSIZE WSAEMSGSIZE
+#define EPROTOTYPE WSAEPROTOTYPE
+#define ENOPROTOOPT WSAENOPROTOOPT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define EADDRINUSE WSAEADDRINUSE
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#define ENETDOWN WSAENETDOWN
+#define ENETUNREACH WSAENETUNREACH
+#define ENETRESET WSAENETRESET
+#define ECONNABORTED WSAECONNABORTED
+#define ECONNRESET WSAECONNRESET
+#define ENOBUFS WSAENOBUFS
+#define EISCONN WSAEISCONN
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#define ETIMEDOUT WSAETIMEDOUT
+#define ECONNREFUSED WSAECONNREFUSED
+#define ELOOP WSAELOOP
+#define EHOSTDOWN WSAEHOSTDOWN
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+
+#endif
+
+#undef XP_WIN
+#undef XP_UNIX
+#undef RESOURCE_STR_X
+#undef RESOURCE_STR
+
+#define XP_UNIX 1
+#define RESOURCE_STR 1
+
+#include "allxpstr.h"
+
+const char *
+SECU_Strerror(int error)
+{
+ char * errString;
+ int16 err = error + RES_OFFSET;
+
+ errString = mcom_include_merrors_i_strings(err) ;
+ if (!errString)
+ errString = mcom_include_secerr_i_strings(err) ;
+ if (!errString)
+ errString = mcom_include_sslerr_i_strings(err) ;
+ if (!errString)
+ errString = mcom_include_xp_error_i_strings(err) ;
+ if (!errString)
+ errString = mcom_include_xp_msg_i_strings(err) ;
+ if (!errString)
+ errString = "ERROR NOT FOUND! \n";
+
+/* printf( "%s\n", errString); */
+
+ return (const char *)errString;
+}
+
diff --git a/security/nss/cmd/lib/stubs.c b/security/nss/cmd/lib/stubs.c
new file mode 100644
index 000000000..6dfafcb66
--- /dev/null
+++ b/security/nss/cmd/lib/stubs.c
@@ -0,0 +1,50 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#include "secport.h" /* for UUID */
+
+#if !defined(SUNOS) && !defined(SUN) && !defined(SOLARIS)
+void SSL_InitHashLock (void)
+ {
+ }
+
+void SSL3_Init (void)
+ {
+ }
+#endif
+
+int
+PREF_GetCharPref(const char *pref_name, char * return_buffer, int * length)
+{
+ assert(0);
+ return -1;
+}