1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #ifndef _SEC_UTIL_H_
5 #define _SEC_UTIL_H_
6 
7 #include "seccomon.h"
8 #include "secitem.h"
9 #include "secport.h"
10 #include "prerror.h"
11 #include "base64.h"
12 #include "keyhi.h"
13 #include "secpkcs7.h"
14 #include "secasn1.h"
15 #include "secder.h"
16 #include <stdio.h>
17 
18 #include "basicutil.h"
19 #include "sslerr.h"
20 #include "sslt.h"
21 #include "blapi.h"
22 
23 #define SEC_CT_PRIVATE_KEY "private-key"
24 #define SEC_CT_PUBLIC_KEY "public-key"
25 #define SEC_CT_CERTIFICATE "certificate"
26 #define SEC_CT_CERTIFICATE_REQUEST "certificate-request"
27 #define SEC_CT_CERTIFICATE_ID "certificate-identity"
28 #define SEC_CT_PKCS7 "pkcs7"
29 #define SEC_CT_PKCS12 "pkcs12"
30 #define SEC_CT_CRL "crl"
31 #define SEC_CT_NAME "name"
32 
33 #define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
34 #define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
35 
36 #define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
37 #define NS_CERT_TRAILER "-----END CERTIFICATE-----"
38 
39 #define NS_CRL_HEADER "-----BEGIN CRL-----"
40 #define NS_CRL_TRAILER "-----END CRL-----"
41 
42 #define SECU_Strerror PORT_ErrorToString
43 
44 typedef struct {
45     enum {
46         PW_NONE = 0,
47         PW_FROMFILE = 1,
48         PW_PLAINTEXT = 2,
49         PW_EXTERNAL = 3
50     } source;
51     char *data;
52 } secuPWData;
53 
54 /*
55 ** Change a password on a token, or initialize a token with a password
56 ** if it does not already have one.
57 ** Use passwd to send the password in plaintext, pwFile to specify a
58 ** file containing the password, or NULL for both to prompt the user.
59 */
60 SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile);
61 
62 /*
63 ** Change a password on a token, or initialize a token with a password
64 ** if it does not already have one.
65 ** In this function, you can specify both the old and new passwords
66 ** as either a string or file. NOTE: any you don't specify will
67 ** be prompted for
68 */
69 SECStatus SECU_ChangePW2(PK11SlotInfo *slot, char *oldPass, char *newPass,
70                          char *oldPwFile, char *newPwFile);
71 
72 /*  These were stolen from the old sec.h... */
73 /*
74 ** Check a password for legitimacy. Passwords must be at least 8
75 ** characters long and contain one non-alphabetic. Return DSTrue if the
76 ** password is ok, DSFalse otherwise.
77 */
78 extern PRBool SEC_CheckPassword(char *password);
79 
80 /*
81 ** Blind check of a password. Complement to SEC_CheckPassword which
82 ** ignores length and content type, just retuning DSTrue is the password
83 ** exists, DSFalse if NULL
84 */
85 extern PRBool SEC_BlindCheckPassword(char *password);
86 
87 /*
88 ** Get a password.
89 ** First prompt with "msg" on "out", then read the password from "in".
90 ** The password is then checked using "chkpw".
91 */
92 extern char *SEC_GetPassword(FILE *in, FILE *out, char *msg,
93                              PRBool (*chkpw)(char *));
94 
95 char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg);
96 
97 char *SECU_GetPasswordString(void *arg, char *prompt);
98 
99 /*
100 ** Write a dongle password.
101 ** Uses MD5 to hash constant system data (hostname, etc.), and then
102 ** creates RC4 key to encrypt a password "pw" into a file "fd".
103 */
104 extern SECStatus SEC_WriteDongleFile(int fd, char *pw);
105 
106 /*
107 ** Get a dongle password.
108 ** Uses MD5 to hash constant system data (hostname, etc.), and then
109 ** creates RC4 key to decrypt and return a password from file "fd".
110 */
111 extern char *SEC_ReadDongleFile(int fd);
112 
113 /* End stolen headers */
114 
115 /* Just sticks the two strings together with a / if needed */
116 char *SECU_AppendFilenameToDir(char *dir, char *filename);
117 
118 /* Returns result of PR_GetEnvSecure("SSL_DIR") or NULL */
119 extern char *SECU_DefaultSSLDir(void);
120 
121 /*
122 ** Should be called once during initialization to set the default
123 **    directory for looking for cert.db, key.db, and cert-nameidx.db files
124 ** Removes trailing '/' in 'base'
125 ** If 'base' is NULL, defaults to set to .netscape in home directory.
126 */
127 extern char *SECU_ConfigDirectory(const char *base);
128 
129 /*
130 ** Basic callback function for SSL_GetClientAuthDataHook
131 */
132 extern int
133 SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
134                        struct CERTDistNamesStr *caNames,
135                        struct CERTCertificateStr **pRetCert,
136                        struct SECKEYPrivateKeyStr **pRetKey);
137 
138 extern PRBool SECU_GetWrapEnabled(void);
139 extern void SECU_EnableWrap(PRBool enable);
140 
141 extern PRBool SECU_GetUtf8DisplayEnabled(void);
142 extern void SECU_EnableUtf8Display(PRBool enable);
143 
144 /* revalidate the cert and print information about cert verification
145  * failure at time == now */
146 extern void
147 SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
148                        CERTCertificate *cert, PRBool checksig,
149                        SECCertificateUsage certUsage, void *pinArg, PRBool verbose);
150 
151 /* revalidate the cert and print information about cert verification
152  * failure at specified time */
153 extern void
154 SECU_printCertProblemsOnDate(FILE *outfile, CERTCertDBHandle *handle,
155                              CERTCertificate *cert, PRBool checksig, SECCertificateUsage certUsage,
156                              void *pinArg, PRBool verbose, PRTime datetime);
157 
158 /* print out CERTVerifyLog info. */
159 extern void
160 SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
161                       PRBool verbose);
162 
163 /* Read in a DER from a file, may be ascii  */
164 extern SECStatus
165 SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii,
166                      PRBool warnOnPrivateKeyInAsciiFile);
167 
168 /* Print integer value and hex */
169 extern void SECU_PrintInteger(FILE *out, const SECItem *i, const char *m,
170                               int level);
171 
172 /* Print ObjectIdentifier symbolically */
173 extern SECOidTag SECU_PrintObjectID(FILE *out, const SECItem *oid,
174                                     const char *m, int level);
175 
176 /* Print AlgorithmIdentifier symbolically */
177 extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m,
178                                   int level);
179 
180 /*
181  * Format and print the UTC Time "t".  If the tag message "m" is not NULL,
182  * do indent formatting based on "level" and add a newline afterward;
183  * otherwise just print the formatted time string only.
184  */
185 extern void SECU_PrintUTCTime(FILE *out, const SECItem *t, const char *m,
186                               int level);
187 
188 /*
189  * Format and print the Generalized Time "t".  If the tag message "m"
190  * is not NULL, * do indent formatting based on "level" and add a newline
191  * afterward; otherwise just print the formatted time string only.
192  */
193 extern void SECU_PrintGeneralizedTime(FILE *out, const SECItem *t,
194                                       const char *m, int level);
195 
196 /*
197  * Format and print the UTC or Generalized Time "t".  If the tag message
198  * "m" is not NULL, do indent formatting based on "level" and add a newline
199  * afterward; otherwise just print the formatted time string only.
200  */
201 extern void SECU_PrintTimeChoice(FILE *out, const SECItem *t, const char *m,
202                                  int level);
203 
204 /* callback for listing certs through pkcs11 */
205 extern SECStatus SECU_PrintCertNickname(CERTCertListNode *cert, void *data);
206 
207 /* Dump all certificate nicknames in a database */
208 extern SECStatus
209 SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc *out,
210                            PRBool sortByName, PRBool sortByTrust);
211 
212 /* See if nickname already in database. Return 1 true, 0 false, -1 error */
213 int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname);
214 
215 /* Dump contents of cert req */
216 extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m,
217                                         int level);
218 
219 /* Dump contents of certificate */
220 extern int SECU_PrintCertificate(FILE *out, const SECItem *der, const char *m,
221                                  int level);
222 
223 extern int SECU_PrintCertificateBasicInfo(FILE *out, const SECItem *der, const char *m,
224                                           int level);
225 
226 extern int SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
227                                             int level);
228 
229 /* Dump contents of a DER certificate name (issuer or subject) */
230 extern int SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level);
231 
232 /* print trust flags on a cert */
233 extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m,
234                                  int level);
235 
236 extern int SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m,
237                                           int level);
238 
239 /* Dump contents of private key */
240 extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
241 
242 /* Dump contents of an RSA public key */
243 extern void SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level);
244 
245 /* Dump contents of a DSA public key */
246 extern void SECU_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level);
247 
248 /* Print the MD5 and SHA1 fingerprints of a cert */
249 extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m,
250                                   int level);
251 
252 /* Pretty-print any PKCS7 thing */
253 extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m,
254                                       int level);
255 /* Pretty-print a pkcs12 file */
256 extern SECStatus SECU_PrintPKCS12(FILE *out, const SECItem *der, char *m, int level);
257 /* Init PKCS11 stuff */
258 extern SECStatus SECU_PKCS11Init(PRBool readOnly);
259 
260 /* Dump contents of signed data */
261 extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
262                                 int level, SECU_PPFunc inner);
263 
264 /* Dump contents of signed data, excluding the signature */
265 extern int SECU_PrintSignedContent(FILE *out, SECItem *der, char *m, int level,
266                                    SECU_PPFunc inner);
267 
268 /* Print cert data and its trust flags */
269 extern SECStatus SEC_PrintCertificateAndTrust(CERTCertificate *cert,
270                                               const char *label,
271                                               CERTCertTrust *trust);
272 
273 extern int SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level);
274 
275 extern void
276 SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level);
277 
278 extern void SECU_PrintString(FILE *out, const SECItem *si, const char *m,
279                              int level);
280 extern void SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level);
281 
282 extern void SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level);
283 extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
284                                                   char *msg, int level);
285 
286 extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
287                                  char *msg, int level);
288 
289 extern void SECU_PrintNameQuotesOptional(FILE *out, CERTName *name,
290                                          const char *msg, int level,
291                                          PRBool quotes);
292 extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg,
293                            int level);
294 extern void SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level);
295 
296 #ifdef SECU_GetPassword
297 /* Convert a High public Key to a Low public Key */
298 extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
299 #endif
300 
301 extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
302 
303 extern SECStatus DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw);
304 
305 extern char *SECU_SECModDBName(void);
306 
307 /* Fetch and register an oid if it hasn't been done already */
308 extern void SECU_cert_fetchOID(SECOidTag *data, const SECOidData *src);
309 
310 extern SECStatus SECU_RegisterDynamicOids(void);
311 
312 /* Identifies hash algorithm tag by its string representation. */
313 extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg);
314 
315 /* Store CRL in output file or pk11 db. Also
316  * encodes with base64 and exports to file if ascii flag is set
317  * and file is not NULL. */
318 extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl,
319                                PRFileDesc *outFile, PRBool ascii, char *url);
320 
321 /*
322 ** DER sign a single block of data using private key encryption and the
323 ** MD5 hashing algorithm. This routine first computes a digital signature
324 ** using SEC_SignData, then wraps it with an CERTSignedData and then der
325 ** encodes the result.
326 **     "arena" is the memory arena to use to allocate data from
327 **     "sd" returned CERTSignedData
328 **     "result" the final der encoded data (memory is allocated)
329 **     "buf" the input data to sign
330 **     "len" the amount of data to sign
331 **     "pk" the private key to encrypt with
332 */
333 extern SECStatus SECU_DerSignDataCRL(PLArenaPool *arena, CERTSignedData *sd,
334                                      unsigned char *buf, int len,
335                                      SECKEYPrivateKey *pk, SECOidTag algID);
336 
337 typedef enum {
338     noKeyFound = 1,
339     noSignatureMatch = 2,
340     failToEncode = 3,
341     failToSign = 4,
342     noMem = 5
343 } SignAndEncodeFuncExitStat;
344 
345 extern SECStatus
346 SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
347                       SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode);
348 
349 extern SECStatus
350 SECU_CopyCRL(PLArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl);
351 
352 /*
353 ** Finds the crl Authority Key Id extension. Returns NULL if no such extension
354 ** was found.
355 */
356 CERTAuthKeyID *
357 SECU_FindCRLAuthKeyIDExten(PLArenaPool *arena, CERTSignedCrl *crl);
358 
359 /*
360  * Find the issuer of a crl. Cert usage should be checked before signing a crl.
361  */
362 CERTCertificate *
363 SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem *subject,
364                    CERTAuthKeyID *id, PRTime validTime);
365 
366 /* call back function used in encoding of an extension. Called from
367  * SECU_EncodeAndAddExtensionValue */
368 typedef SECStatus (*EXTEN_EXT_VALUE_ENCODER)(PLArenaPool *extHandleArena,
369                                              void *value, SECItem *encodedValue);
370 
371 /* Encodes and adds extensions to the CRL or CRL entries. */
372 SECStatus
373 SECU_EncodeAndAddExtensionValue(PLArenaPool *arena, void *extHandle,
374                                 void *value, PRBool criticality, int extenType,
375                                 EXTEN_EXT_VALUE_ENCODER EncodeValueFn);
376 
377 /* Caller ensures that dst is at least item->len*2+1 bytes long */
378 void
379 SECU_SECItemToHex(const SECItem *item, char *dst);
380 
381 /* Requires 0x prefix. Case-insensitive. Will do in-place replacement if
382  * successful */
383 SECStatus
384 SECU_SECItemHexStringToBinary(SECItem *srcdest);
385 
386 /* Parse a version range string, with "min" and "max" version numbers,
387  * separated by colon (":"), and return the result in vr and v2.
388  *
389  * Both min and max values are optional.
390  * The following syntax is used to specify the enabled protocol versions:
391  * A string with only a max value is expected as ":{max}",
392  * and all implemented versions less than or equal to max will be enabled.
393  * A string with only a min value is expected as "{min}:",
394  * and all implemented versions greater than or equal to min will be enabled.
395  * A string consisting of a colon only means "all versions enabled".
396  *
397  * In order to avoid a link dependency from libsectool to libssl,
398  * the caller must provide the desired default values for the min/max values,
399  * by providing defaultVersionRange (which can be obtained from libssl by
400  * calling SSL_VersionRangeGetSupported).
401  */
402 SECStatus
403 SECU_ParseSSLVersionRangeString(const char *input,
404                                 const SSLVersionRange defaultVersionRange,
405                                 SSLVersionRange *vrange);
406 
407 SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
408                          unsigned int *enabledGroupsCount);
409 SECStatus parseSigSchemeList(const char *arg,
410                              const SSLSignatureScheme **enabledSigSchemes,
411                              unsigned int *enabledSigSchemeCount);
412 typedef struct {
413     SECItem label;
414     PRBool hasContext;
415     SECItem context;
416     unsigned int outputLength;
417 } secuExporter;
418 
419 SECStatus parseExporters(const char *arg,
420                          const secuExporter **enabledExporters,
421                          unsigned int *enabledExporterCount);
422 
423 SECStatus exportKeyingMaterials(PRFileDesc *fd,
424                                 const secuExporter *exporters,
425                                 unsigned int exporterCount);
426 
427 SECStatus readPSK(const char *arg, SECItem *psk, SECItem *label);
428 
429 /*
430  *
431  *  Error messaging
432  *
433  */
434 
435 void printflags(char *trusts, unsigned int flags);
436 
437 #if !defined(XP_UNIX) && !defined(XP_OS2)
438 extern int ffs(unsigned int i);
439 #endif
440 
441 /* Finds certificate by searching it in the DB or by examinig file
442  * in the local directory. */
443 CERTCertificate *
444 SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle,
445                                   char *name, PRBool ascii,
446                                   void *pwarg);
447 #include "secerr.h"
448 #include "sslerr.h"
449 
450 #endif /* _SEC_UTIL_H_ */
451