michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #ifndef _SEC_UTIL_H_ michael@0: #define _SEC_UTIL_H_ michael@0: michael@0: #include "seccomon.h" michael@0: #include "secitem.h" michael@0: #include "secport.h" michael@0: #include "prerror.h" michael@0: #include "base64.h" michael@0: #include "key.h" michael@0: #include "secpkcs7.h" michael@0: #include "secasn1.h" michael@0: #include "secder.h" michael@0: #include michael@0: michael@0: #include "basicutil.h" michael@0: #include "sslerr.h" michael@0: #include "sslt.h" michael@0: michael@0: michael@0: #define SEC_CT_PRIVATE_KEY "private-key" michael@0: #define SEC_CT_PUBLIC_KEY "public-key" michael@0: #define SEC_CT_CERTIFICATE "certificate" michael@0: #define SEC_CT_CERTIFICATE_REQUEST "certificate-request" michael@0: #define SEC_CT_CERTIFICATE_ID "certificate-identity" michael@0: #define SEC_CT_PKCS7 "pkcs7" michael@0: #define SEC_CT_CRL "crl" michael@0: #define SEC_CT_NAME "name" michael@0: michael@0: #define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----" michael@0: #define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----" michael@0: michael@0: #define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----" michael@0: #define NS_CERT_TRAILER "-----END CERTIFICATE-----" michael@0: michael@0: #define NS_CRL_HEADER "-----BEGIN CRL-----" michael@0: #define NS_CRL_TRAILER "-----END CRL-----" michael@0: michael@0: #define SECU_Strerror PORT_ErrorToString michael@0: michael@0: michael@0: typedef struct { michael@0: enum { michael@0: PW_NONE = 0, michael@0: PW_FROMFILE = 1, michael@0: PW_PLAINTEXT = 2, michael@0: PW_EXTERNAL = 3 michael@0: } source; michael@0: char *data; michael@0: } secuPWData; michael@0: michael@0: /* michael@0: ** Change a password on a token, or initialize a token with a password michael@0: ** if it does not already have one. michael@0: ** Use passwd to send the password in plaintext, pwFile to specify a michael@0: ** file containing the password, or NULL for both to prompt the user. michael@0: */ michael@0: SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile); michael@0: michael@0: /* michael@0: ** Change a password on a token, or initialize a token with a password michael@0: ** if it does not already have one. michael@0: ** In this function, you can specify both the old and new passwords michael@0: ** as either a string or file. NOTE: any you don't specify will michael@0: ** be prompted for michael@0: */ michael@0: SECStatus SECU_ChangePW2(PK11SlotInfo *slot, char *oldPass, char *newPass, michael@0: char *oldPwFile, char *newPwFile); michael@0: michael@0: /* These were stolen from the old sec.h... */ michael@0: /* michael@0: ** Check a password for legitimacy. Passwords must be at least 8 michael@0: ** characters long and contain one non-alphabetic. Return DSTrue if the michael@0: ** password is ok, DSFalse otherwise. michael@0: */ michael@0: extern PRBool SEC_CheckPassword(char *password); michael@0: michael@0: /* michael@0: ** Blind check of a password. Complement to SEC_CheckPassword which michael@0: ** ignores length and content type, just retuning DSTrue is the password michael@0: ** exists, DSFalse if NULL michael@0: */ michael@0: extern PRBool SEC_BlindCheckPassword(char *password); michael@0: michael@0: /* michael@0: ** Get a password. michael@0: ** First prompt with "msg" on "out", then read the password from "in". michael@0: ** The password is then checked using "chkpw". michael@0: */ michael@0: extern char *SEC_GetPassword(FILE *in, FILE *out, char *msg, michael@0: PRBool (*chkpw)(char *)); michael@0: michael@0: char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg); michael@0: michael@0: char *SECU_GetPasswordString(void *arg, char *prompt); michael@0: michael@0: /* michael@0: ** Write a dongle password. michael@0: ** Uses MD5 to hash constant system data (hostname, etc.), and then michael@0: ** creates RC4 key to encrypt a password "pw" into a file "fd". michael@0: */ michael@0: extern SECStatus SEC_WriteDongleFile(int fd, char *pw); michael@0: michael@0: /* michael@0: ** Get a dongle password. michael@0: ** Uses MD5 to hash constant system data (hostname, etc.), and then michael@0: ** creates RC4 key to decrypt and return a password from file "fd". michael@0: */ michael@0: extern char *SEC_ReadDongleFile(int fd); michael@0: michael@0: michael@0: /* End stolen headers */ michael@0: michael@0: /* Just sticks the two strings together with a / if needed */ michael@0: char *SECU_AppendFilenameToDir(char *dir, char *filename); michael@0: michael@0: /* Returns result of getenv("SSL_DIR") or NULL */ michael@0: extern char *SECU_DefaultSSLDir(void); michael@0: michael@0: /* michael@0: ** Should be called once during initialization to set the default michael@0: ** directory for looking for cert.db, key.db, and cert-nameidx.db files michael@0: ** Removes trailing '/' in 'base' michael@0: ** If 'base' is NULL, defaults to set to .netscape in home directory. michael@0: */ michael@0: extern char *SECU_ConfigDirectory(const char* base); michael@0: michael@0: /* michael@0: ** Basic callback function for SSL_GetClientAuthDataHook michael@0: */ michael@0: extern int michael@0: SECU_GetClientAuthData(void *arg, PRFileDesc *fd, michael@0: struct CERTDistNamesStr *caNames, michael@0: struct CERTCertificateStr **pRetCert, michael@0: struct SECKEYPrivateKeyStr **pRetKey); michael@0: michael@0: extern PRBool SECU_GetWrapEnabled(void); michael@0: extern void SECU_EnableWrap(PRBool enable); michael@0: michael@0: extern PRBool SECU_GetUtf8DisplayEnabled(void); michael@0: extern void SECU_EnableUtf8Display(PRBool enable); michael@0: michael@0: /* revalidate the cert and print information about cert verification michael@0: * failure at time == now */ michael@0: extern void michael@0: SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle, michael@0: CERTCertificate *cert, PRBool checksig, michael@0: SECCertificateUsage certUsage, void *pinArg, PRBool verbose); michael@0: michael@0: /* revalidate the cert and print information about cert verification michael@0: * failure at specified time */ michael@0: extern void michael@0: SECU_printCertProblemsOnDate(FILE *outfile, CERTCertDBHandle *handle, michael@0: CERTCertificate *cert, PRBool checksig, SECCertificateUsage certUsage, michael@0: void *pinArg, PRBool verbose, PRTime datetime); michael@0: michael@0: /* print out CERTVerifyLog info. */ michael@0: extern void michael@0: SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log, michael@0: PRBool verbose); michael@0: michael@0: /* Read in a DER from a file, may be ascii */ michael@0: extern SECStatus michael@0: SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii, michael@0: PRBool warnOnPrivateKeyInAsciiFile); michael@0: michael@0: /* Print integer value and hex */ michael@0: extern void SECU_PrintInteger(FILE *out, const SECItem *i, const char *m, michael@0: int level); michael@0: michael@0: /* Print ObjectIdentifier symbolically */ michael@0: extern SECOidTag SECU_PrintObjectID(FILE *out, const SECItem *oid, michael@0: const char *m, int level); michael@0: michael@0: /* Print AlgorithmIdentifier symbolically */ michael@0: extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, michael@0: int level); michael@0: michael@0: /* michael@0: * Format and print the UTC Time "t". If the tag message "m" is not NULL, michael@0: * do indent formatting based on "level" and add a newline afterward; michael@0: * otherwise just print the formatted time string only. michael@0: */ michael@0: extern void SECU_PrintUTCTime(FILE *out, const SECItem *t, const char *m, michael@0: int level); michael@0: michael@0: /* michael@0: * Format and print the Generalized Time "t". If the tag message "m" michael@0: * is not NULL, * do indent formatting based on "level" and add a newline michael@0: * afterward; otherwise just print the formatted time string only. michael@0: */ michael@0: extern void SECU_PrintGeneralizedTime(FILE *out, const SECItem *t, michael@0: const char *m, int level); michael@0: michael@0: /* michael@0: * Format and print the UTC or Generalized Time "t". If the tag message michael@0: * "m" is not NULL, do indent formatting based on "level" and add a newline michael@0: * afterward; otherwise just print the formatted time string only. michael@0: */ michael@0: extern void SECU_PrintTimeChoice(FILE *out, const SECItem *t, const char *m, michael@0: int level); michael@0: michael@0: /* callback for listing certs through pkcs11 */ michael@0: extern SECStatus SECU_PrintCertNickname(CERTCertListNode* cert, void *data); michael@0: michael@0: /* Dump all certificate nicknames in a database */ michael@0: extern SECStatus michael@0: SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc* out, michael@0: PRBool sortByName, PRBool sortByTrust); michael@0: michael@0: /* See if nickname already in database. Return 1 true, 0 false, -1 error */ michael@0: int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname); michael@0: michael@0: /* Dump contents of cert req */ michael@0: extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, michael@0: int level); michael@0: michael@0: /* Dump contents of certificate */ michael@0: extern int SECU_PrintCertificate(FILE *out, const SECItem *der, const char *m, michael@0: int level); michael@0: michael@0: extern int SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m, michael@0: int level); michael@0: michael@0: /* Dump contents of a DER certificate name (issuer or subject) */ michael@0: extern int SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level); michael@0: michael@0: /* print trust flags on a cert */ michael@0: extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, michael@0: int level); michael@0: michael@0: extern int SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m, michael@0: int level); michael@0: michael@0: #ifdef HAVE_EPV_TEMPLATE michael@0: /* Dump contents of private key */ michael@0: extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level); michael@0: #endif michael@0: michael@0: /* Dump contents of an RSA public key */ michael@0: extern void SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level); michael@0: michael@0: /* Dump contents of a DSA public key */ michael@0: extern void SECU_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level); michael@0: michael@0: /* Print the MD5 and SHA1 fingerprints of a cert */ michael@0: extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, michael@0: int level); michael@0: michael@0: /* Pretty-print any PKCS7 thing */ michael@0: extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m, michael@0: int level); michael@0: michael@0: /* Init PKCS11 stuff */ michael@0: extern SECStatus SECU_PKCS11Init(PRBool readOnly); michael@0: michael@0: /* Dump contents of signed data */ michael@0: extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m, michael@0: int level, SECU_PPFunc inner); michael@0: michael@0: /* Dump contents of signed data, excluding the signature */ michael@0: extern int SECU_PrintSignedContent(FILE *out, SECItem *der, char *m, int level, michael@0: SECU_PPFunc inner); michael@0: michael@0: /* Print cert data and its trust flags */ michael@0: extern SECStatus SEC_PrintCertificateAndTrust(CERTCertificate *cert, michael@0: const char *label, michael@0: CERTCertTrust *trust); michael@0: michael@0: extern int SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level); michael@0: michael@0: extern void michael@0: SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level); michael@0: michael@0: extern void SECU_PrintString(FILE *out, const SECItem *si, const char *m, michael@0: int level); michael@0: extern void SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level); michael@0: michael@0: extern void SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level); michael@0: extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value, michael@0: char *msg, int level); michael@0: michael@0: extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions, michael@0: char *msg, int level); michael@0: michael@0: extern void SECU_PrintNameQuotesOptional(FILE *out, CERTName *name, michael@0: const char *msg, int level, michael@0: PRBool quotes); michael@0: extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg, michael@0: int level); michael@0: extern void SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level); michael@0: michael@0: #ifdef SECU_GetPassword michael@0: /* Convert a High public Key to a Low public Key */ michael@0: extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey); michael@0: #endif michael@0: michael@0: extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg); michael@0: michael@0: extern SECStatus DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw); michael@0: michael@0: extern char *SECU_SECModDBName(void); michael@0: michael@0: /* Fetch and register an oid if it hasn't been done already */ michael@0: extern void SECU_cert_fetchOID(SECOidTag *data, const SECOidData *src); michael@0: michael@0: extern SECStatus SECU_RegisterDynamicOids(void); michael@0: michael@0: /* Identifies hash algorithm tag by its string representation. */ michael@0: extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg); michael@0: michael@0: /* Store CRL in output file or pk11 db. Also michael@0: * encodes with base64 and exports to file if ascii flag is set michael@0: * and file is not NULL. */ michael@0: extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl, michael@0: PRFileDesc *outFile, PRBool ascii, char *url); michael@0: michael@0: michael@0: /* michael@0: ** DER sign a single block of data using private key encryption and the michael@0: ** MD5 hashing algorithm. This routine first computes a digital signature michael@0: ** using SEC_SignData, then wraps it with an CERTSignedData and then der michael@0: ** encodes the result. michael@0: ** "arena" is the memory arena to use to allocate data from michael@0: ** "sd" returned CERTSignedData michael@0: ** "result" the final der encoded data (memory is allocated) michael@0: ** "buf" the input data to sign michael@0: ** "len" the amount of data to sign michael@0: ** "pk" the private key to encrypt with michael@0: */ michael@0: extern SECStatus SECU_DerSignDataCRL(PLArenaPool *arena, CERTSignedData *sd, michael@0: unsigned char *buf, int len, michael@0: SECKEYPrivateKey *pk, SECOidTag algID); michael@0: michael@0: typedef enum { michael@0: noKeyFound = 1, michael@0: noSignatureMatch = 2, michael@0: failToEncode = 3, michael@0: failToSign = 4, michael@0: noMem = 5 michael@0: } SignAndEncodeFuncExitStat; michael@0: michael@0: extern SECStatus michael@0: SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl, michael@0: SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode); michael@0: michael@0: extern SECStatus michael@0: SECU_CopyCRL(PLArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl); michael@0: michael@0: /* michael@0: ** Finds the crl Authority Key Id extension. Returns NULL if no such extension michael@0: ** was found. michael@0: */ michael@0: CERTAuthKeyID * michael@0: SECU_FindCRLAuthKeyIDExten (PLArenaPool *arena, CERTSignedCrl *crl); michael@0: michael@0: /* michael@0: * Find the issuer of a crl. Cert usage should be checked before signing a crl. michael@0: */ michael@0: CERTCertificate * michael@0: SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem* subject, michael@0: CERTAuthKeyID* id, PRTime validTime); michael@0: michael@0: michael@0: /* call back function used in encoding of an extension. Called from michael@0: * SECU_EncodeAndAddExtensionValue */ michael@0: typedef SECStatus (* EXTEN_EXT_VALUE_ENCODER) (PLArenaPool *extHandleArena, michael@0: void *value, SECItem *encodedValue); michael@0: michael@0: /* Encodes and adds extensions to the CRL or CRL entries. */ michael@0: SECStatus michael@0: SECU_EncodeAndAddExtensionValue(PLArenaPool *arena, void *extHandle, michael@0: void *value, PRBool criticality, int extenType, michael@0: EXTEN_EXT_VALUE_ENCODER EncodeValueFn); michael@0: michael@0: /* Caller ensures that dst is at least item->len*2+1 bytes long */ michael@0: void michael@0: SECU_SECItemToHex(const SECItem * item, char * dst); michael@0: michael@0: /* Requires 0x prefix. Case-insensitive. Will do in-place replacement if michael@0: * successful */ michael@0: SECStatus michael@0: SECU_SECItemHexStringToBinary(SECItem* srcdest); michael@0: michael@0: /* Parse a version range string, with "min" and "max" version numbers, michael@0: * separated by colon (":"), and return the result in vr and v2. michael@0: * michael@0: * Both min and max values are optional. michael@0: * The following syntax is used to specify the enabled protocol versions: michael@0: * A string with only a max value is expected as ":{max}", michael@0: * and all implemented versions less than or equal to max will be enabled. michael@0: * A string with only a min value is expected as "{min}:", michael@0: * and all implemented versions greater than or equal to min will be enabled. michael@0: * A string consisting of a colon only means "all versions enabled". michael@0: * michael@0: * Because output parameter type SSLVersionRange doesn't allow to set michael@0: * version 2 values, we use a separate boolean output parameter michael@0: * to return whether SSL 2 is enabled. michael@0: * michael@0: * In order to avoid a link dependency from libsectool to libssl, michael@0: * the caller must provide the desired default values for the min/max values, michael@0: * by providing defaultEnableSSL2 and defaultVersionRange michael@0: * (which can be obtained from libssl by calling SSL_VersionRangeGetSupported). michael@0: */ michael@0: SECStatus michael@0: SECU_ParseSSLVersionRangeString(const char *input, michael@0: const SSLVersionRange defaultVersionRange, michael@0: const PRBool defaultEnableSSL2, michael@0: SSLVersionRange *vrange, michael@0: PRBool *enableSSL2); michael@0: michael@0: /* michael@0: * michael@0: * Error messaging michael@0: * michael@0: */ michael@0: michael@0: void printflags(char *trusts, unsigned int flags); michael@0: michael@0: #if !defined(XP_UNIX) && !defined(XP_OS2) michael@0: extern int ffs(unsigned int i); michael@0: #endif michael@0: michael@0: /* Finds certificate by searching it in the DB or by examinig file michael@0: * in the local directory. */ michael@0: CERTCertificate* michael@0: SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle, michael@0: char *name, PRBool ascii, michael@0: void *pwarg); michael@0: #include "secerr.h" michael@0: #include "sslerr.h" michael@0: michael@0: #endif /* _SEC_UTIL_H_ */