diff options
Diffstat (limited to 'security/nss/cmd/lib')
-rw-r--r-- | security/nss/cmd/lib/Makefile | 75 | ||||
-rw-r--r-- | security/nss/cmd/lib/NSPRerrs.h | 150 | ||||
-rw-r--r-- | security/nss/cmd/lib/SECerrs.h | 442 | ||||
-rw-r--r-- | security/nss/cmd/lib/SSLerrs.h | 366 | ||||
-rw-r--r-- | security/nss/cmd/lib/berparse.c | 404 | ||||
-rw-r--r-- | security/nss/cmd/lib/config.mk | 43 | ||||
-rw-r--r-- | security/nss/cmd/lib/derprint.c | 619 | ||||
-rw-r--r-- | security/nss/cmd/lib/dongle.c | 249 | ||||
-rw-r--r-- | security/nss/cmd/lib/fe_util.c | 40 | ||||
-rw-r--r-- | security/nss/cmd/lib/ffs.c | 48 | ||||
-rw-r--r-- | security/nss/cmd/lib/filestub.c | 1118 | ||||
-rw-r--r-- | security/nss/cmd/lib/makefile.win | 66 | ||||
-rw-r--r-- | security/nss/cmd/lib/manifest.mn | 68 | ||||
-rw-r--r-- | security/nss/cmd/lib/secarb.c | 372 | ||||
-rw-r--r-- | security/nss/cmd/lib/seccnames.c | 202 | ||||
-rw-r--r-- | security/nss/cmd/lib/secerror.c | 107 | ||||
-rw-r--r-- | security/nss/cmd/lib/secpwd.c | 187 | ||||
-rw-r--r-- | security/nss/cmd/lib/secutil.c | 2583 | ||||
-rw-r--r-- | security/nss/cmd/lib/secutil.h | 327 | ||||
-rw-r--r-- | security/nss/cmd/lib/sslstubs.c | 74 | ||||
-rw-r--r-- | security/nss/cmd/lib/strerror.c | 127 | ||||
-rw-r--r-- | security/nss/cmd/lib/stubs.c | 50 |
22 files changed, 7717 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..833361e41 --- /dev/null +++ b/security/nss/cmd/lib/seccnames.c @@ -0,0 +1,202 @@ +/* + * 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" +#include <sys/stat.h> +#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..57c4aac5f --- /dev/null +++ b/security/nss/cmd/lib/secpwd.c @@ -0,0 +1,187 @@ +/* + * 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 + +#ifdef _WINDOWS +#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 *)) +{ + char phrase[200]; + int infd = fileno(input); +#if defined(_WINDOWS) || defined(OS2) + int isTTY = (input == stdin); +#else + int isTTY = isatty(infd); +#endif + 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) + { + c = getch(); + + 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..f7cfb8d59 --- /dev/null +++ b/security/nss/cmd/lib/secutil.c @@ -0,0 +1,2583 @@ +/* + * 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" +#include <sys/stat.h> +#include <stdarg.h> +#include <errno.h> + +#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); + fprintf(stderr, ": %s\n", strerror(errno)); + 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 = 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 = 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; + } + + 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; +} |