1 /*
2  *  Copyright (C) 2007 Red Hat, Inc.
3  *
4  *  Permission is hereby granted, free of charge, to any person obtaining a
5  *  copy of this software and associated documentation files (the
6  *  "Software"), to deal in the Software without restriction, including
7  *  without limitation the rights to use, copy, modify, merge, publish,
8  *  distribute, sublicense, and/or sell copies of the Software, and to
9  *  permit persons to whom the Software is furnished to do so, subject
10  *  to the following conditions:
11  *
12  *  The above copyright notice and this permission notice shall be
13  *  included in all copies or substantial portions of the Software.
14  *
15  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  *  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  *  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  *  SOFTWARE.
23 */
24 
25 #include <unistd.h>
26 #include <stdio.h>
27 #include "nss_compat_ossl.h"
28 #include <secder.h>
29 #include <secmod.h>
30 #include <termios.h> /* for echo on/off */
31 #include <sys/stat.h>
32 #include <errno.h>
33 #include <private/pprio.h>
34 
35 typedef struct {
36     PRFileDesc         *pssl;
37     PRBool              server;
38     int                 shutdown_flags;
39     PLHashTable        *appdata;
40     int                 error;
41     long                session_timeout;
42     int                 verify_mode;
43     int                 verify_result;
44     void               *info_cb;
45     void               *verify_cb;
46     PLArenaPool        *arena;
47     CK_SLOT_ID          slotID;
48     char               *nickname;
49     char               *slotname;
50 } ossl_ctx_t;
51 
52 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
53                 (x)->pValue=(v); (x)->ulValueLen = (l);
54 
55 #define CERT_NewTempCertificate __CERT_NewTempCertificate
56 
57 /* functions for handling token passwords */
58 static char * nss_password_prompt(PK11SlotInfo *slot, PRBool retry, void *arg);
59 static char * nss_no_password(PK11SlotInfo *slot, PRBool retry, void *arg);
60 static char * nss_get_password(FILE *input, FILE *output, PK11SlotInfo *slot, PRBool (*ok)(unsigned char *), PRUint32 retry);
61 static PRBool nss_check_password(unsigned char *cp);
62 static void echoOff(int fd);
63 static void echoOn(int fd);
64 
65 /* Global variables for the NSPR I/O layer */
66 static PRDescIdentity    gIdentity = PR_INVALID_IO_LAYER;
67 static PRDescIdentity    gBioIdentity = PR_INVALID_IO_LAYER;
68 static PRIOMethods       gMethods;
69 static PRIOMethods       gBioMethods;
70 
71 /* Global for the password prompt */
72 static char * prompt;
73 
74 /* Global for per-application data storage */
75 static int ex_data_index = 0;
76 
77 /* Declarations for functions to handle per-connection data */
78 static ossl_ctx_t * nss_get_private(PRFileDesc *fd);
79 static int nss_set_private(PRFileDesc *fd, PRFilePrivate *data);
80 
81 int is_initialized = 0;
82 static const char* pem_library = "libnsspem.so";
83 static const char* root_certs_library = "libnssckbi.so";
84 
85 static SECMODModule* pemMod = NULL;
86 static SECMODModule* rootMod = NULL;
87 CK_SLOT_ID slotCount = 1;
88 
89 #define DEF_SSL2_TIMEOUT        100L  /* seconds */
90 #define DEF_SSL3_TIMEOUT      86400L  /* 24 hours */
91 
92 /* Cipher definitions */
93 typedef struct
94 {
95     char *ossl_name;    /* The OpenSSL cipher name */
96     int num;            /* The cipher id */
97     int attr;           /* cipher attributes: algorithms, etc */
98     int version;        /* protocol version valid for this cipher */
99     int bits;           /* bits of strength */
100     int alg_bits;       /* bits of the algorithm */
101     int strength;       /* LOW, MEDIUM, HIGH */
102     int enabled;        /* Enabled by default? */
103     int client_only;    /* Allowed only on clients */
104 } cipher_properties;
105 
106 #define ciphernum 22
107 
108 /* Some local cipher definitions I don't want to share with apps */
109 
110 /* cipher attributes  */
111 #define SSL_kRSA  0x00000001L
112 #define SSL_aRSA  0x00000002L
113 #define SSL_aDSS  0x00000004L
114 #define SSL_DSS   SSL_aDSS
115 #define SSL_eNULL 0x00000008L
116 #define SSL_DES   0x00000010L
117 #define SSL_3DES  0x00000020L
118 #define SSL_RC4   0x00000040L
119 #define SSL_RC2   0x00000080L
120 #define SSL_AES   0x00000100L
121 #define SSL_MD5   0x00000200L
122 #define SSL_SHA1  0x00000400L
123 #define SSL_SHA   SSL_SHA1
124 #define SSL_RSA   (SSL_kRSA|SSL_aRSA)
125 #define SSL_kEDH  0x00000800L
126 #define SSL_EDH   (SSL_kEDH)
127 
128 /* cipher strength */
129 #define SSL_NULL      0x00000001L
130 #define SSL_EXPORT40  0x00000002L
131 #define SSL_EXPORT56  0x00000004L
132 #define SSL_LOW       0x00000008L
133 #define SSL_MEDIUM    0x00000010L
134 #define SSL_HIGH      0x00000020L
135 
136 #define SSL2  0x00000001L
137 #define SSL3  0x00000002L
138 /* OpenSSL treats SSL3 and TLSv1 the same */
139 #define TLS1  SSL3
140 
141 /* Cipher translation */
142 static cipher_properties ciphers_def[ciphernum] =
143 {
144     /* SSL 2 ciphers */
145     {"DES-CBC3-MD5", SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_MD5, SSL2, 168, 168, SSL_HIGH, SSL_ALLOWED, PR_FALSE},
146     {"RC2-CBC-MD5", SSL_EN_RC2_128_CBC_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSL2, 128, 128, SSL_MEDIUM, SSL_ALLOWED, PR_FALSE},
147     {"RC4-MD5", SSL_EN_RC4_128_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL2, 128, 128, SSL_MEDIUM, SSL_ALLOWED, PR_FALSE},
148     {"DES-CBC-MD5", SSL_EN_DES_64_CBC_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_MD5, SSL2, 56, 56, SSL_LOW, SSL_ALLOWED, PR_FALSE},
149     {"EXP-RC2-CBC-MD5", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSL2, 40, 128, SSL_EXPORT40, SSL_ALLOWED, PR_FALSE},
150     {"EXP-RC4-MD5", SSL_EN_RC4_128_EXPORT40_WITH_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL2, 40, 128, SSL_EXPORT40, SSL_ALLOWED, PR_FALSE},
151 
152     /* SSL3 ciphers */
153     {"RC4-MD5", SSL_RSA_WITH_RC4_128_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL3, 128, 128, SSL_MEDIUM, SSL_ALLOWED, PR_FALSE},
154     {"RC4-SHA", SSL_RSA_WITH_RC4_128_SHA, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA1, SSL3, 128, 128, SSL_MEDIUM, SSL_NOT_ALLOWED, PR_FALSE},
155     {"DES-CBC3-SHA", SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_SHA1, SSL3, 168, 168, SSL_HIGH, SSL_ALLOWED, PR_FALSE},
156     {"DES-CBC-SHA", SSL_RSA_WITH_DES_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1, SSL3, 56, 56, SSL_LOW, SSL_ALLOWED, PR_FALSE},
157     {"EXP-RC4-MD5", SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSL3, 40, 128, SSL_EXPORT40, SSL_ALLOWED, PR_FALSE},
158     {"EXP-RC2-CBC-MD5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSL3, 0, 0, SSL_EXPORT40, SSL_ALLOWED, PR_FALSE},
159     {"NULL-MD5", SSL_RSA_WITH_NULL_MD5, SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_MD5, SSL3, 0, 0, SSL_NULL, SSL_NOT_ALLOWED, PR_FALSE},
160     {"NULL-SHA", SSL_RSA_WITH_NULL_SHA, SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_SHA1, SSL3, 0, 0, SSL_NULL, SSL_NOT_ALLOWED, PR_FALSE},
161 
162     /* TLSv1 ciphers */
163     {"EXP1024-DES-CBC-SHA", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA, TLS1, 56, 56, SSL_EXPORT56, SSL_ALLOWED, PR_FALSE},
164     {"EXP1024-RC4-SHA", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA, TLS1, 56, 56, SSL_EXPORT56, SSL_ALLOWED, PR_FALSE},
165     {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA, TLS1, 128, 128, SSL_HIGH, SSL_ALLOWED, PR_FALSE},
166     {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA, TLS1, 256, 256, SSL_HIGH, SSL_ALLOWED, PR_FALSE},
167 
168     /* Diffie-Hellman ciphers for clients only */
169     {"DHE-DSS-AES256-SHA", TLS_DH_DSS_WITH_AES_256_CBC_SHA, SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA, TLS1, 256, 256, SSL_HIGH, SSL_ALLOWED, PR_TRUE},
170     {"DHE-RSA-AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA, SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA, TLS1, 256, 256, SSL_HIGH, SSL_ALLOWED, PR_TRUE},
171     {"DHE-DSS-AES128-SHA",TLS_DHE_DSS_WITH_AES_128_CBC_SHA,  SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA, TLS1, 128, 128, SSL_HIGH, SSL_ALLOWED, PR_TRUE},
172     {"DHE-RSA-AES128-SHA",TLS_DHE_RSA_WITH_AES_128_CBC_SHA,  SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA, TLS1, 128, 128, SSL_HIGH, SSL_ALLOWED, PR_TRUE},
173 
174 };
175 
176 /*
177  * cipher_list is an integer array with the following values:
178  *   -1: never enable this cipher
179  *    0: cipher disabled
180  *    1: cipher enabled
181  */
nss_parse_ciphers(const char * cipherstr,int cipher_list[ciphernum])182 int nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
183 {
184     int i;
185     char *cipher;
186     char *ciphers;
187     char *ciphertip;
188     int action;
189     int rv;
190 
191     /* All disabled to start */
192     for (i=0; i<ciphernum; i++)
193         cipher_list[i] = 0;
194 
195     ciphertip = strdup(cipherstr);
196     cipher = ciphers = ciphertip;
197 
198     while (ciphers && (strlen(ciphers)))
199     {
200         while ((*cipher) && (isspace(*cipher)))
201             ++cipher;
202 
203         action = 1;
204         switch(*cipher)
205         {
206             case '+': /* Add something */
207                 action = 1;
208                 cipher++;
209                 break;
210             case '-': /* Subtract something */
211                 action = 0;
212                 cipher++;
213                 break;
214             case '!':  /* Disable something */
215                 action = -1;
216                 cipher++;
217                 break;
218             default:
219                /* do nothing */
220                 break;
221         }
222 
223         if ((ciphers = strchr(cipher, ':'))) {
224             *ciphers++ = '\0';
225         }
226 
227         /* Do the easy one first */
228         if (!strcmp(cipher, "ALL")) {
229             for (i=0; i<ciphernum; i++) {
230                 if (!(ciphers_def[i].attr & SSL_eNULL))
231                     cipher_list[i] = action;
232             }
233         } else if (!strcmp(cipher, "COMPLEMENTOFALL")) {
234             for (i=0; i<ciphernum; i++) {
235                 if ((ciphers_def[i].attr & SSL_eNULL))
236                     cipher_list[i] = action;
237             }
238         } else if (!strcmp(cipher, "DEFAULT")) {
239             for (i=0; i<ciphernum; i++) {
240                 cipher_list[i] = ciphers_def[i].enabled == SSL_ALLOWED ? 1 : 0;
241             }
242         } else {
243             int mask = 0;
244             int strength = 0;
245             int protocol = 0;
246             char *c;
247 
248             c = cipher;
249             while (c && (strlen(c))) {
250 
251                 if ((c = strchr(cipher, '+'))) {
252                     *c++ = '\0';
253                 }
254 
255                 if (!strcmp(cipher, "RSA")) {
256                     mask |= SSL_RSA;
257                 } else if (!strcmp(cipher, "EDH")) {
258                     mask |= SSL_EDH;
259                 } else if ((!strcmp(cipher, "NULL")) || (!strcmp(cipher, "eNULL"))) {
260                     mask |= SSL_eNULL;
261                 } else if (!strcmp(cipher, "AES")) {
262                     mask |= SSL_AES;
263                 } else if (!strcmp(cipher, "3DES")) {
264                     mask |= SSL_3DES;
265                 } else if (!strcmp(cipher, "DES")) {
266                     mask |= SSL_DES;
267                 } else if (!strcmp(cipher, "RC4")) {
268                     mask |= SSL_RC4;
269                 } else if (!strcmp(cipher, "RC2")) {
270                     mask |= SSL_RC2;
271                 } else if (!strcmp(cipher, "MD5")) {
272                     mask |= SSL_MD5;
273                 } else if ((!strcmp(cipher, "SHA")) || (!strcmp(cipher, "SHA1"))) {
274                     mask |= SSL_SHA1;
275                 } else if (!strcmp(cipher, "SSLv2")) {
276                     protocol |= SSL2;
277                 } else if (!strcmp(cipher, "SSLv3")) {
278                     protocol |= SSL3;
279                 } else if (!strcmp(cipher, "TLSv1")) {
280                     protocol |= TLS1;
281                 } else if (!strcmp(cipher, "HIGH")) {
282                     strength |= SSL_HIGH;
283                 } else if (!strcmp(cipher, "MEDIUM")) {
284                     strength |= SSL_MEDIUM;
285                 } else if (!strcmp(cipher, "LOW")) {
286                     strength |= SSL_LOW;
287                 } else if ((!strcmp(cipher, "EXPORT")) || (!strcmp(cipher, "EXP"))) {
288                     strength |= SSL_EXPORT40|SSL_EXPORT56;
289                 } else if (!strcmp(cipher, "EXPORT40")) {
290                     strength |= SSL_EXPORT40;
291                 } else if (!strcmp(cipher, "EXPORT56")) {
292                     strength |= SSL_EXPORT56;
293                 }
294 
295                 if (c)
296                     cipher = c;
297 
298             } /* while */
299 
300             /* If we have a mask, apply it. If not then perhaps they provided
301              * a specific cipher to enable.
302              */
303             if (mask || strength || protocol)
304                 for (i=0; i<ciphernum; i++) {
305                     if (((ciphers_def[i].attr & mask) ||
306                      (ciphers_def[i].strength & strength) ||
307                      (ciphers_def[i].version & protocol)) &&
308                      (cipher_list[i] != -1)) {
309                         /* Enable the NULL ciphers only if explicity
310                          * requested */
311                         if (ciphers_def[i].attr & SSL_eNULL) {
312                             if (mask & SSL_eNULL)
313                                 cipher_list[i] = action;
314                         } else
315                             cipher_list[i] = action;
316                     }
317                 }
318             else {
319                 for (i=0; i<ciphernum; i++) {
320                     if (!strcmp(ciphers_def[i].ossl_name, cipher) &&
321                         cipher_list[1] != -1)
322                         cipher_list[i] = action;
323                 }
324             }
325         }
326 
327         if (ciphers)
328             cipher = ciphers;
329 
330     }
331 
332     /* See if any ciphers were enabled */
333     rv = 0;
334     for (i=0; i<ciphernum; i++) {
335         if (cipher_list[i] == 1)
336             rv = 1;
337     }
338 
339     free(ciphertip);
340 
341     return rv;
342 }
343 
344 static PRStatus PR_CALLBACK
layer_close(PRFileDesc * fd)345 layer_close(PRFileDesc *fd)
346 {
347     return PR_SUCCESS;
348 }
349 
350 
351 /* Hashing function for application-specific data (ex_data). */
HashFunc(const void * key)352 static PLHashNumber HashFunc(const void * key)
353 {
354    return (PLHashNumber) key;
355 }
356 
new_ossl(PRFileDesc * s)357 ossl_ctx_t *new_ossl(PRFileDesc *s)
358 {
359     ossl_ctx_t *ossl;
360 
361     ossl = (ossl_ctx_t *)malloc(sizeof(ossl_ctx_t));
362 
363     ossl->pssl = (PRFileDesc *)s;
364     ossl->shutdown_flags = 0;
365     ossl->appdata = PL_NewHashTable(10, HashFunc, PL_CompareValues, PL_CompareValues, NULL, NULL);;
366     ossl->slotID = -1;
367     ossl->slotname = NULL;
368     ossl->error = 0;
369     ossl->session_timeout = -1;
370     ossl->verify_mode = 0;
371     ossl->verify_result = 0;
372     ossl->server = 0;
373     ossl->info_cb = NULL;
374     ossl->verify_cb = NULL;
375     ossl->arena = PORT_NewArena(1024); /* This size is arbitrary */
376     ossl->nickname = NULL;
377 
378     return ossl;
379 }
380 
free_ossl(ossl_ctx_t * ossl)381 int free_ossl(ossl_ctx_t *ossl)
382 {
383     if (!ossl)
384         return 0;
385 
386     PL_HashTableDestroy(ossl->appdata);
387 
388     PORT_FreeArena(ossl->arena, PR_FALSE);
389 
390     free(ossl);
391 
392     return 0;
393 }
394 
395 SECStatus
BadCertHandler(void * arg,PRFileDesc * ssl)396 BadCertHandler(void *arg, PRFileDesc *ssl)
397 {
398     SECStatus success = SECSuccess;
399     PRErrorCode err;
400     ossl_ctx_t *ossl;
401 
402     if (!ssl) {
403         return SECFailure;
404     }
405 
406     ossl = nss_get_private(ssl);
407 
408     err = PORT_GetError();
409 
410     switch (err) {
411     case SEC_ERROR_CERT_VALID:
412     case SSL_ERROR_BAD_CERT_DOMAIN: /* We don't set set the hostname so we can
413                                      * safely ignore this. In OpenSSL the
414                                      * caller is responsible. */
415         err = X509_V_OK;
416         break;
417     /* let the handshake continue unless otherwise specified */
418     case SEC_ERROR_UNTRUSTED_ISSUER:
419     case SEC_ERROR_UNKNOWN_ISSUER:
420     case SEC_ERROR_EXPIRED_CERTIFICATE:
421         if (ossl->verify_mode & SSL_VERIFY_PEER)
422             success = SECFailure;
423         break;
424     default:
425         /* FIXME: There must be some circumstances where the handshake will
426          * fail?
427          */
428         success = SECFailure;
429         break;
430     }
431 
432     ossl->verify_result = err;
433 
434     return success;
435 }
436 
437 SECStatus
AuthCertificateHandler(void * arg,PRFileDesc * ssl,PRBool checksig,PRBool isServer)438 AuthCertificateHandler(void *arg, PRFileDesc *ssl,
439                        PRBool checksig, PRBool isServer)
440 {
441     ossl_ctx_t *ossl;
442     int rv;
443     SECStatus status;
444     int (*verify_callback)(int preverify_ok, X509_STORE_CTX *x509_ctx);
445 
446     ossl = nss_get_private(ssl);
447 
448     status = SSL_AuthCertificate(arg, ssl, checksig, isServer);
449 
450     /* If the user has requested their own verification callback them
451      * use it. Otherwise fall back to the one provided by NSS.
452      */
453     if (ossl->verify_cb != NULL) {
454 	X509_STORE_CTX ctx;
455 
456         verify_callback = ossl->verify_cb;
457 
458 	ctx.current_cert = SSL_get_peer_certificate(ssl);
459 	ctx.error = PORT_GetError();
460         rv = verify_callback((status == SECSuccess) ? 1 : 0, &ctx);
461 	X509_free(ctx.current_cert);
462 
463         if (rv == 1) {
464             ossl->verify_result = X509_V_OK;
465             return SECSuccess;
466         } else {
467             ossl->verify_result = PR_GetError();
468             return SECFailure;
469         }
470     }
471 
472     return status;
473 }
474 
475 /*
476  * Duplicated, non-exported function from NSS that compares 2 certificate
477  * times.
478  */
479 PRBool
cert_IsNewer(CERTCertificate * certa,CERTCertificate * certb)480 cert_IsNewer(CERTCertificate *certa, CERTCertificate *certb)
481 {
482     PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
483     SECStatus rv;
484     PRBool newerbefore, newerafter;
485 
486     newerbefore = newerafter = PR_FALSE;
487 
488     rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
489     if ( rv != SECSuccess ) {
490         return(PR_FALSE);
491     }
492 
493     rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
494     if ( rv != SECSuccess ) {
495         return(PR_TRUE);
496     }
497 
498     if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
499         newerbefore = PR_TRUE;
500     }
501 
502     if ( LL_CMP(notAfterA, >, notAfterB) ) {
503         newerafter = PR_TRUE;
504     }
505 
506     if ( newerbefore && newerafter ) {
507         return(PR_TRUE);
508     }
509 
510     if ( ( !newerbefore ) && ( !newerafter ) ) {
511         return(PR_FALSE);
512     }
513 
514     /* get current UTC time */
515     now = PR_Now();
516 
517     if ( newerbefore ) {
518         /* cert A was issued after cert B, but expires sooner */
519         /* if A is expired, then pick B */
520         if ( LL_CMP(notAfterA, <, now ) ) {
521             return(PR_FALSE);
522         }
523         return(PR_TRUE);
524     } else {
525         /* cert B was issued after cert A, but expires sooner */
526         /* if B is expired, then pick A */
527         if ( LL_CMP(notAfterB, <, now ) ) {
528             return(PR_TRUE);
529         }
530         return(PR_FALSE);
531     }
532 }
533 
534 /*
535  * Given a nickname, find the "best" certificate available for that
536  * certificate (for the case of multiple CN's with different usages, a
537  * renewed cert that is not yet valid, etc). The best is defined as the
538  * newest, valid server certificate.
539  */
540 CERTCertificate*
FindServerCertFromNickname(const char * name)541 FindServerCertFromNickname(const char* name)
542 {
543     CERTCertList* clist;
544     CERTCertificate* bestcert = NULL;
545 
546     CERTCertListNode *cln;
547     PRUint32 bestCertMatchedUsage = 0;
548     PRBool bestCertIsValid = PR_FALSE;
549 
550     if (name == NULL)
551         return NULL;
552 
553     clist = PK11_ListCerts(PK11CertListUser, NULL);
554 
555     for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln,clist);
556         cln = CERT_LIST_NEXT(cln)) {
557         CERTCertificate* cert = cln->cert;
558         const char* nickname = (const char*) cln->appData;
559         if (!nickname) {
560             nickname = cert->nickname;
561         }
562         if (strcmp(name, nickname) == 0) {
563             PRUint32 matchedUsage = 0;
564             PRBool isValid = PR_FALSE;
565             PRBool swapcert = PR_FALSE;
566             /* We still need to check key usage. Dual-key certs appear
567              * as 2 certs in the list with different usages. We want to pick
568              * the "best" one, preferrably the one with certUsageSSLServer.
569              * Otherwise just return the cert if the nickname matches.
570              */
571             if (CERT_CheckCertUsage(cert, certUsageSSLServer) == SECSuccess) {
572                 matchedUsage = 2;
573             } else {
574                 if (CERT_CheckCertUsage(cert, certUsageEmailRecipient) == SECSuccess)
575                 {
576                     matchedUsage = 1;
577                 }
578             }
579 
580             if (secCertTimeValid == CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE))
581             {
582                 /* This is a valid certificate. */
583                 isValid = PR_TRUE;
584             }
585             if (!bestcert) {
586                 /* We didn't have a cert picked yet, automatically choose this
587                  * one.
588                  */
589                 swapcert = PR_TRUE;
590             } else {
591                 if (matchedUsage > bestCertMatchedUsage) {
592                     /* The cert previously picked didn't have the correct
593                      * usage, but this one does. Choose this one.
594                      */
595                     swapcert = PR_TRUE;
596                 } else {
597                     if ( (bestCertMatchedUsage == matchedUsage) &&
598                     (((PR_FALSE == bestCertIsValid) && (PR_TRUE == isValid)) ||
599                     ((PR_TRUE == bestCertIsValid == isValid) && (PR_TRUE == cert_IsNewer(cert, bestcert))))) {
600                         /* The cert previously picked was invalid but this one
601                          * is. Or they were both valid but this one is newer.
602                          */
603                         swapcert = PR_TRUE;
604                     }
605                 }
606             }
607 
608             if (swapcert == PR_TRUE)
609             {
610                 bestcert = cert;
611                 bestCertMatchedUsage = matchedUsage;
612                 bestCertIsValid = isValid;
613             }
614         }
615     }
616     if (bestcert) {
617         bestcert = CERT_DupCertificate(bestcert);
618     }
619     if (clist) {
620         CERT_DestroyCertList(clist);
621     }
622     return bestcert;
623 }
624 
625 /*
626  * Executed automatically when the SSL handshake is completed.
627  * Call the final handshake callback if one was set.
628  */
nss_HandshakeCallback(PRFileDesc * ssl,void * arg)629 SECStatus nss_HandshakeCallback(PRFileDesc *ssl, void *arg)
630 {
631     ossl_ctx_t *ossl;
632     void (*info_callback)(const SSL *ssl, int type, int val);
633 
634     ossl = nss_get_private(ssl);
635 
636     info_callback = ossl->info_cb;
637 
638     if (info_callback)
639         info_callback(ssl, SSL_CB_HANDSHAKE_DONE, 1);
640 
641     return SECSuccess;
642 }
643 
nss_Init_Tokens()644 SECStatus nss_Init_Tokens()
645 {
646     PK11SlotList        *slotList;
647     PK11SlotListElement *listEntry;
648     SECStatus ret, status = SECSuccess;
649     int retryCount = 0;
650 
651     PK11_SetPasswordFunc(nss_password_prompt);
652 
653     slotList = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL);
654 
655     for (listEntry = PK11_GetFirstSafe(slotList);
656         listEntry;
657         listEntry = listEntry->next)
658     {
659         PK11SlotInfo *slot = listEntry->slot;
660 
661         if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) {
662 #if 0
663             if (slot == PK11_GetInternalKeySlot()) {
664                 log("The server key database has not been initialized.");
665             } else {
666                 log("The token %s has not been initialized.", PK11_GetTokenName(slot));
667             }
668 #endif
669             PK11_FreeSlot(slot);
670             continue;
671         }
672 
673         ret = PK11_Authenticate(slot, PR_TRUE, &retryCount);
674         if (SECSuccess != ret) {
675 #if 0
676             log("Password for slot %s is incorrect.", PK11_GetTokenName(slot));
677 #endif
678             PK11_FreeSlot(slot);
679             return SECFailure;
680         }
681         retryCount = 0; /* reset counter to 0 for the next token */
682         PK11_FreeSlot(slot);
683     }
684 
685 #if 0
686     /*
687      * reset NSS password callback to blank, so that the server won't prompt
688      * again after initialization is done.
689      */
690     PK11_SetPasswordFunc(nss_no_password);
691 #endif
692 
693     return status;
694 }
695 
696 /*
697  * Wrapper callback function that prompts the user for the token password
698  * up to 3 times.
699  */
700 static char *
nss_password_prompt(PK11SlotInfo * slot,PRBool retry,void * arg)701 nss_password_prompt(PK11SlotInfo *slot, PRBool retry, void *arg)
702 {
703     char *passwd = NULL;
704     int *pRetryCount = (int *)arg;
705 
706     if (pRetryCount && retry) {
707         (*pRetryCount)++;
708     }
709     prompt = PR_smprintf("Please enter password for \"%s\" token:", PK11_GetTokenName(slot));
710     if (pRetryCount == NULL) {
711         /* should not happen */
712         passwd = nss_get_password(stdin, stdout, slot, nss_check_password, 0);
713     } else {
714         if (*pRetryCount > 2) {
715             passwd = NULL; /* abort after 2 retries (3 failed attempts) */
716         } else {
717             passwd = nss_get_password(stdin, stdout, slot, nss_check_password, *pRetryCount);
718         }
719     }
720 
721     return passwd;
722 }
723 
nss_check_password(unsigned char * cp)724 static PRBool nss_check_password(unsigned char *cp)
725 {
726     unsigned int i;
727     int nchar = 0;      /* number of characters */
728     int ntrail = 0;     /* number of trailing bytes to follow */
729     int ndigit = 0;     /* number of decimal digits */
730     int nlower = 0;     /* number of ASCII lowercase letters */
731     int nupper = 0;     /* number of ASCII uppercase letters */
732     int nnonalnum = 0;  /* number of ASCII non-alphanumeric characters */
733     int nnonascii = 0;  /* number of non-ASCII characters */
734     int nclass;         /* number of character classes */
735     int ulPinLen;
736 
737     ulPinLen = strlen((char *)cp);
738 
739     /* We'll give non-FIPS users a pass */
740     if (!PK11_IsFIPS())
741         return PR_TRUE;
742 
743     for (i = 0; i < ulPinLen; i++) {
744         unsigned int byte = cp[i];
745 
746         if (ntrail) {
747             if ((byte & 0xc0) != 0x80) {
748                 /* illegal */
749                 nchar = -1;
750                 break;
751             }
752             if (--ntrail == 0) {
753                 nchar++;
754                 nnonascii++;
755             }
756             continue;
757         }
758         if ((byte & 0x80) == 0x00) {
759             /* single-byte (ASCII) character */
760             nchar++;
761             if (isdigit(byte)) {
762                 if (i < ulPinLen - 1) {
763                     ndigit++;
764                 }
765             } else if (islower(byte)) {
766                 nlower++;
767             } else if (isupper(byte)) {
768                 if (i > 0) {
769                     nupper++;
770                 }
771             } else {
772                 nnonalnum++;
773             }
774         } else if ((byte & 0xe0) == 0xc0) {
775             /* leading byte of two-byte character */
776             ntrail = 1;
777         } else if ((byte & 0xf0) == 0xe0) {
778             /* leading byte of three-byte character */
779             ntrail = 2;
780         } else if ((byte & 0xf8) == 0xf0) {
781             /* leading byte of four-byte character */
782             ntrail = 3;
783         } else {
784             /* illegal */
785             nchar = -1;
786             break;
787         }
788     }
789 
790     if (nchar == -1) {
791         /* illegal UTF8 string */
792         return PR_FALSE;
793     }
794     if (nchar < 7) {
795         return PR_FALSE;
796     }
797     nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
798              (nnonalnum != 0) + (nnonascii != 0);
799     if (nclass < 3) {
800         return PR_FALSE;
801     }
802     return PR_TRUE;
803 }
804 
805 /*
806  * Password callback so the user is not prompted to enter the password
807  * after the server starts.
808  */
nss_no_password(PK11SlotInfo * slot,PRBool retry,void * arg)809 static char * nss_no_password(PK11SlotInfo *slot, PRBool retry, void *arg)
810 {
811     return NULL;
812 }
813 
814 /*
815  * Password callback to prompt the user for a password. This requires
816  * twiddling with the tty. Alternatively, if the file password.conf
817  * exists then it may be used to store the token password(s).
818  */
nss_get_password(FILE * input,FILE * output,PK11SlotInfo * slot,PRBool (* ok)(unsigned char *),PRUint32 retry)819 static char *nss_get_password(FILE *input, FILE *output,
820                                        PK11SlotInfo *slot,
821                                        PRBool (*ok)(unsigned char *),
822                                        PRUint32 retry)
823 {
824     char *token_name = NULL;
825 #ifdef RETRIEVE_PASSWORD_FROM_FILE
826     int tmp;
827     char *pwdstr = NULL;
828     FILE *pwd_fileptr;
829     char *ptr;
830     char line[1024];
831 #endif
832     unsigned char phrase[200];
833     int infd = fileno(input);
834     int isTTY = isatty(infd);
835 
836     token_name = PK11_GetTokenName(slot);
837 
838 #ifdef RETRIEVE_PASSWORD_FROM_FILE
839         /* Try to get the passwords from the password file if it exists.
840          * THIS IS UNSAFE and is provided for convenience only. Without this
841          * capability the server would have to be started in foreground mode.
842          */
843         if ((*parg->mc->pphrase_dialog_path != '\0') &&
844            ((pwd_fileptr = fopen(parg->mc->pphrase_dialog_path, "r")) != NULL)) {
845             while(fgets(line, 1024, pwd_fileptr)) {
846                 if (PL_strstr(line, token_name) == line) {
847                     tmp = PL_strlen(line) - 1;
848                     while((line[tmp] == ' ') || (line[tmp] == '\n'))
849                         tmp--;
850                     line[tmp+1] = '\0';
851                     ptr = PL_strchr(line, ':');
852                     if (ptr == NULL) {
853                         ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
854                            "Malformed password entry for token %s. Format should be token:password", token_name);
855                         continue;
856                     }
857                     for(tmp=1; ptr[tmp] == ' '; tmp++) {}
858                     pwdstr = strdup(&(ptr[tmp]));
859                 }
860             }
861             fclose(pwd_fileptr);
862         } else {
863             log_error("Unable to open password file %s", parg->mc->pphrase_dialog_path);
864         }
865     }
866 #endif
867 
868     for (;;) {
869         /* Prompt for password */
870         if (isTTY) {
871             if (retry > 0) {
872                 fprintf(output, "Password incorrect. Please try again.\n");
873             }
874             fprintf(output, "%s", prompt);
875             echoOff(infd);
876         }
877         fgets((char*) phrase, sizeof(phrase), input);
878         if (isTTY) {
879             fprintf(output, "\n");
880             echoOn(infd);
881         }
882         /* stomp on newline */
883         phrase[strlen((char*)phrase)-1] = 0;
884 
885         /* Validate password */
886         if (!(*ok)(phrase)) {
887             /* Not weird enough */
888             if (!isTTY) return 0;
889             fprintf(output, "Password must be at least 7 characters long with a mix\n");
890             fprintf(output, "of upper-case, lower-case, digits, punctuation and\n");
891             fprintf(output, "non-ASCII characters.\n");
892             continue;
893         }
894         return (char*) PORT_Strdup((char*)phrase);
895     }
896 }
897 
898 /*
899  * Turn the echoing off on a tty.
900  */
901 static void echoOff(int fd)
902 {
903     if (isatty(fd)) {
904         struct termios tio;
905         tcgetattr(fd, &tio);
906         tio.c_lflag &= ~ECHO;
907         tcsetattr(fd, TCSAFLUSH, &tio);
908     }
909 }
910 
911 /*
912  * Turn the echoing on on a tty.
913  */
914 static void echoOn(int fd)
915 {
916     if (isatty(fd)) {
917         struct termios tio;
918         tcgetattr(fd, &tio);
919         tio.c_lflag |= ECHO;
920         tcsetattr(fd, TCSAFLUSH, &tio);
921         tcsetattr(fd, TCSAFLUSH, &tio);
922     }
923 }
924 
925 /**
926  *
927  * Callback to pick the SSL client certificate.
928  */
929 SECStatus nss_SelectClientCert(void *arg, PRFileDesc * fd,
930                                struct CERTDistNamesStr * caNames,
931                                struct CERTCertificateStr ** pRetCert,
932                                struct SECKEYPrivateKeyStr ** pRetKey)
933 {
934     CERTCertificate *cert;
935     SECKEYPrivateKey *privKey;
936     ossl_ctx_t *ossl = (ossl_ctx_t *)arg;
937     void *proto_win = NULL;
938     SECStatus secStatus = SECFailure;
939 
940     proto_win = SSL_RevealPinArg(fd);
941 
942     cert = PK11_FindCertFromNickname(ossl->nickname, proto_win);
943     if (cert) {
944         if (ossl->slotname != NULL) {
945             PK11SlotInfo *slot;
946             slot = PK11_FindSlotByName(ossl->slotname);
947             privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
948             PK11_FreeSlot(slot);
949         } else {
950             privKey = PK11_FindKeyByAnyCert(cert, proto_win);
951         }
952         if (privKey) {
953             secStatus = SECSuccess;
954         }
955         else {
956             CERT_DestroyCertificate(cert);
957         }
958   }
959 
960   if (secStatus == SECSuccess) {
961       *pRetCert = cert;
962       *pRetKey = privKey;
963   }
964 
965   return secStatus;
966 }
967 
968 /*
969  * See if the file exists.
970  *
971  * If file exists returns 1
972  * otherwise return 0
973  */
974 static int file_exists(const char *filename) {
975   struct stat st;
976 
977   if (filename == NULL)
978     return 0;
979 
980   if (stat(filename, &st) == 0) {
981     if (S_ISREG(st.st_mode))
982       return 1;
983   }
984   return 0;
985 }
986 
987 static int
988 nss_set_server_cert(SSL_CTX *ctx, const char *filename, PRBool cacert)
989 {
990     ossl_ctx_t *ossl;
991     CERTCertificate *cert;
992     void *proto_win = NULL;
993 #ifdef PKCS11_PEM_MODULE
994     CK_SLOT_ID slotID = 0;
995     PK11SlotInfo * slot = NULL;
996     PK11GenericObject *rv;
997     CK_ATTRIBUTE *attrs;
998     CK_ATTRIBUTE theTemplate[20];
999     CK_BBOOL cktrue = CK_TRUE;
1000     CK_BBOOL ckfalse = CK_FALSE;
1001     CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
1002     char nickname[256];
1003 #endif
1004     char *n;
1005 
1006     ossl = nss_get_private(ctx);
1007     if (!ossl) {
1008         return 0;
1009     }
1010 
1011     /* If there is no slash in the filename it is assumed to be a regular
1012      * NSS nickname.
1013      */
1014     if (file_exists(filename)) {
1015         n = strrchr(filename, '/');
1016         if (n) {
1017             n++;
1018         }
1019         if (pemMod == NULL) /* we have a file-based cert but no PEM module */
1020             return 1;
1021     } else {
1022         if (cacert)
1023             return 0; /* You can't specify an NSS CA nickname this way */
1024         /* A nickname from the NSS internal database */
1025         ossl->nickname = strdup(filename);
1026         goto done;
1027     }
1028 
1029 #ifdef PKCS11_PEM_MODULE
1030     attrs = theTemplate;
1031 
1032     /* All CA and trust objects go into slot 0. Other slots are used
1033      * for storing certificates. With each new user certificate we increment
1034      * the slot count.
1035      */
1036     if (cacert) {
1037         slotID = 0;
1038     } else if (ossl->slotID == -1) {
1039         ossl->slotID = slotCount++;
1040         slotID = ossl->slotID;
1041     }
1042 
1043     ossl->slotname = PORT_ArenaAlloc(ossl->arena, 32);
1044     snprintf(ossl->slotname, 32, "PEM Token #%ld", slotID);
1045     snprintf(nickname, 256, "PEM Token #%ld:%s", slotID, n);
1046 
1047     slot = PK11_FindSlotByName(ossl->slotname);
1048 
1049     if (!slot)
1050         return 0;
1051 
1052     PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
1053     PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
1054     PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)filename, strlen(filename)+1); attrs++;
1055     if (cacert) {
1056         PK11_SETATTRS(attrs, CKA_TRUST, &cktrue, sizeof(CK_BBOOL) ); attrs++;
1057     } else {
1058         PK11_SETATTRS(attrs, CKA_TRUST, &ckfalse, sizeof(CK_BBOOL) ); attrs++;
1059     }
1060 
1061     /* This load the certificate in our PEM module into the appropriate
1062      * slot.
1063      */
1064     rv = PK11_CreateGenericObject(slot, theTemplate, 4, PR_FALSE /* isPerm */);
1065     if (rv == NULL) {
1066         return 0;
1067     }
1068 
1069     if (!cacert)
1070         ossl->nickname = strdup(nickname);
1071 
1072     PK11_FreeSlot(slot);
1073 
1074 #else
1075     /* For the case where we don't have the PKCS#11 driver this could be
1076      * NULL if the filename has a slash in it
1077      */
1078     if (ossl->nickname == NULL)
1079         ossl->nickname = strdup(filename);
1080 #endif
1081 
1082 done:
1083     if (!cacert) {
1084         /* Double-check that the certificate or nickname requested exists in
1085          * either the token or the NSS certificate database.
1086          */
1087         cert = PK11_FindCertFromNickname((char *)ossl->nickname, proto_win);
1088 
1089         /* An invalid nickname was passed in */
1090         if (cert == NULL) {
1091             PR_SetError(SEC_ERROR_UNKNOWN_CERT, 0);
1092             return 0;
1093         }
1094 
1095         CERT_DestroyCertificate(cert);
1096     }
1097 
1098     return 1;
1099 }
1100 
1101 static int
1102 nss_set_client_cert(SSL_CTX *ctx, const char *filename)
1103 {
1104     CERTCertificate *cert;
1105     void *proto_win = NULL;
1106     ossl_ctx_t *ossl;
1107     CK_SLOT_ID slotID;
1108 #ifdef PKCS11_PEM_MODULE
1109     PK11SlotInfo * slot = NULL;
1110     PK11GenericObject *rv;
1111     CK_ATTRIBUTE *attrs;
1112     CK_ATTRIBUTE theTemplate[20];
1113     CK_BBOOL cktrue = CK_TRUE;
1114     CK_BBOOL ckfalse = CK_FALSE;
1115     CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
1116 #endif
1117     char nickname[256];
1118     char *n;
1119 
1120     ossl = nss_get_private(ctx);
1121     if (!ossl) {
1122         return 0;
1123     }
1124 
1125     /* If there is no slash in the filename it is assumed to be a regular
1126      * NSS nickname.
1127      */
1128     n = strrchr(filename, '/');
1129     if (n) {
1130         n++;
1131         ossl->slotID = slotCount++;
1132         slotID = ossl->slotID;
1133         snprintf(nickname, 256, "PEM Token #%ld:%s", slotID, n);
1134     } else {
1135         /* A nickname from the NSS internal database */
1136         ossl->nickname = strdup(filename);
1137         goto done;
1138     }
1139 
1140 #ifdef PKCS11_PEM_MODULE
1141     attrs = theTemplate;
1142 
1143     if (ossl->slotname == NULL)
1144         ossl->slotname = PORT_ArenaAlloc(ossl->arena, 32);
1145 
1146     snprintf(ossl->slotname, 32, "PEM Token #%ld", slotID);
1147 
1148     slot = PK11_FindSlotByName(ossl->slotname);
1149 
1150     if (!slot)
1151         return 0;
1152 
1153     PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
1154     PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
1155     PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)filename, strlen(filename)+1); attrs++;
1156     PK11_SETATTRS(attrs, CKA_TRUST, &ckfalse, sizeof(CK_BBOOL) ); attrs++;
1157 
1158     /* This load the certificate in our PEM module into the appropriate
1159      * slot.
1160      */
1161     rv = PK11_CreateGenericObject(slot, theTemplate, 4, PR_FALSE /* isPerm */);
1162 
1163     PK11_FreeSlot(slot);
1164 
1165     if (!rv)
1166         return 0;
1167 
1168     ossl->nickname = strdup(nickname);
1169 #endif
1170 
1171 done:
1172 
1173     cert = PK11_FindCertFromNickname((char *)ossl->nickname, proto_win);
1174 
1175     /* An invalid nickname was passed in */
1176     if (cert == NULL)
1177         return 0;
1178 
1179     CERT_DestroyCertificate(cert);
1180 
1181     if (SSL_GetClientAuthDataHook(ctx,
1182                                  (SSLGetClientAuthData) nss_SelectClientCert,
1183                                  (void *)ossl) != SECSuccess)
1184         return 0;
1185     else
1186         return 1;
1187     return 0;
1188 }
1189 
1190 /*
1191  * Get the data stored in the OSSL translation layer
1192  */
1193 static ossl_ctx_t *
1194 nss_get_private(PRFileDesc *fd)
1195 {
1196     PRFileDesc *layer;
1197 
1198     if (!fd)
1199         return NULL;
1200 
1201     layer = PR_GetIdentitiesLayer(fd, gIdentity);
1202     if (!layer)
1203         return NULL;
1204 
1205     return (ossl_ctx_t *)layer->secret;
1206 }
1207 
1208 /*
1209  * Set the data stored in the OSSL translation layer
1210  */
1211 static int
1212 nss_set_private(PRFileDesc *fd, PRFilePrivate *data)
1213 {
1214     PRFileDesc *layer;
1215 
1216     if (!fd)
1217         return PR_FAILURE;
1218 
1219     layer = PR_GetIdentitiesLayer(fd, gIdentity);
1220     if (!layer)
1221         return PR_FAILURE;
1222 
1223     layer->secret = data;
1224 
1225     return PR_SUCCESS;
1226 }
1227 
1228 /*
1229  * Is it better do to the NSS_Init() here or let the user pass in the
1230  * database location via the command-line?
1231  *
1232  * The SSL_library_init() man page actually advocates ignoring the return
1233  * value. There isn't much we can do about this if the NSS_Init() fails.
1234  *
1235  * The error will appear elsewhere.
1236  */
1237 int SSL_library_init(void)
1238 {
1239     const PRIOMethods *defaultMethods;
1240     char *certDir = NULL;
1241     SECStatus status;
1242 #ifdef PKCS11_PEM_MODULE
1243     char *configstring = NULL;
1244 #endif
1245 
1246     if (is_initialized)
1247         return 1;
1248 
1249     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1);
1250 
1251     certDir = getenv("SSL_DIR"); /* Look in $SSL_DIR */
1252 
1253     if (!certDir) {
1254         certDir = "/etc/pki/nssdb";
1255     }
1256 
1257     if (certDir) {
1258         if (NSS_Init(certDir) != SECSuccess) {
1259             return 1;
1260         }
1261     } else {
1262         if (NSS_NoDB_Init(NULL) != SECSuccess) {
1263             return 1;
1264         }
1265     }
1266 
1267     if (nss_Init_Tokens() != SECSuccess) {
1268         return 1;
1269     }
1270 
1271     status = NSS_SetDomesticPolicy();
1272 
1273     gIdentity = PR_GetUniqueIdentity("NSS_COMPAT_OSSL_Layer");
1274     if (gIdentity == PR_INVALID_IO_LAYER) {
1275 //        log("Failed to init NSS stub layer");
1276     }
1277 
1278     defaultMethods = PR_GetDefaultIOMethods();
1279     if (defaultMethods == NULL) {
1280 //        log("Failed to init NSS stub layer");
1281     }
1282 
1283     /* Our layer has few methods. We use it for storage only */
1284     gMethods = *defaultMethods;
1285 
1286     /* We still need to be able to call PR_Close() so we can free stuff */
1287     gMethods.close = layer_close;
1288 
1289 #ifdef PKCS11_PEM_MODULE
1290     /* Load our PKCS#11 module */
1291     configstring = (char *)malloc(4096);
1292 
1293     PR_snprintf(configstring, 4096, "library=%s name=PEM parameters=\"\"", pem_library);
1294 
1295     pemMod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
1296     if (!pemMod || !pemMod->loaded) {
1297         if (pemMod) {
1298             SECMOD_DestroyModule(pemMod);
1299             pemMod = NULL;
1300         }
1301         free(configstring);
1302         return 1;
1303     }
1304     free(configstring);
1305 #endif
1306 
1307     is_initialized = 1;
1308 
1309     return 1; /* always returns 1 */
1310 }
1311 
1312 static BIO *
1313 nspr_get_bio(PRFileDesc *fd)
1314 {
1315     if (fd->identity != gBioIdentity) {
1316         return NULL;
1317     }
1318     return (BIO *) fd->secret;
1319 }
1320 
1321 static void
1322 nspr_set_bio(PRFileDesc *fd, BIO *bio)
1323 {
1324     if (fd->identity != gBioIdentity) {
1325         return;
1326     }
1327     fd->secret = (PRFilePrivate *) bio;
1328 }
1329 
1330 static PRInt32
1331 nspr_bio_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
1332 {
1333     BIO *bio = nspr_get_bio(fd);
1334     if (!bio) {
1335         return -1;
1336     }
1337 
1338     return bio->m->bwrite(bio, buf, amount);
1339 }
1340 
1341 static PRInt32
1342 nspr_bio_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
1343 				PRIntn flags, PRIntervalTime timeout)
1344 {
1345     BIO *bio = nspr_get_bio(fd);
1346     if (!bio) {
1347         return -1;
1348     }
1349 
1350     return bio->m->bwrite(bio, buf, amount);
1351 }
1352 
1353 static PRInt32
1354 nspr_bio_read(PRFileDesc *fd, void *buf, PRInt32 amount)
1355 {
1356     BIO *bio = nspr_get_bio(fd);
1357 
1358     if (!bio) {
1359         return -1;
1360     }
1361 
1362     return bio->m->bread(bio, buf, amount);
1363 }
1364 
1365 static PRInt32
1366 nspr_bio_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
1367 				PRIntn flags, PRIntervalTime timeout)
1368 {
1369     BIO *bio = nspr_get_bio(fd);
1370 
1371     if (!bio) {
1372         return -1;
1373     }
1374 
1375     return bio->m->bread(bio, buf, amount);
1376 }
1377 
1378 void
1379 npsr_map_error(int err)
1380 {
1381     PRErrorCode prError;
1382 
1383     switch (err ) {
1384         case EACCES:
1385             prError = PR_NO_ACCESS_RIGHTS_ERROR;
1386             break;
1387         case EADDRINUSE:
1388             prError = PR_ADDRESS_IN_USE_ERROR;
1389             break;
1390         case EADDRNOTAVAIL:
1391             prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
1392             break;
1393         case EAFNOSUPPORT:
1394             prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
1395             break;
1396         case EAGAIN:
1397             prError = PR_WOULD_BLOCK_ERROR;
1398             break;
1399         /*
1400          * On QNX and Neutrino, EALREADY is defined as EBUSY.
1401          */
1402 #if EALREADY != EBUSY
1403         case EALREADY:
1404             prError = PR_ALREADY_INITIATED_ERROR;
1405             break;
1406 #endif
1407         case EBADF:
1408             prError = PR_BAD_DESCRIPTOR_ERROR;
1409             break;
1410 #ifdef EBADMSG
1411         case EBADMSG:
1412             prError = PR_IO_ERROR;
1413             break;
1414 #endif
1415         case EBUSY:
1416             prError = PR_FILESYSTEM_MOUNTED_ERROR;
1417             break;
1418         case ECONNABORTED:
1419             prError = PR_CONNECT_ABORTED_ERROR;
1420             break;
1421         case ECONNREFUSED:
1422             prError = PR_CONNECT_REFUSED_ERROR;
1423             break;
1424         case ECONNRESET:
1425             prError = PR_CONNECT_RESET_ERROR;
1426             break;
1427         case EDEADLK:
1428             prError = PR_DEADLOCK_ERROR;
1429             break;
1430 #ifdef EDIRCORRUPTED
1431         case EDIRCORRUPTED:
1432             prError = PR_DIRECTORY_CORRUPTED_ERROR;
1433             break;
1434 #endif
1435 #ifdef EDQUOT
1436         case EDQUOT:
1437             prError = PR_NO_DEVICE_SPACE_ERROR;
1438             break;
1439 #endif
1440         case EEXIST:
1441             prError = PR_FILE_EXISTS_ERROR;
1442             break;
1443         case EFAULT:
1444             prError = PR_ACCESS_FAULT_ERROR;
1445             break;
1446         case EFBIG:
1447             prError = PR_FILE_TOO_BIG_ERROR;
1448             break;
1449         case EHOSTUNREACH:
1450             prError = PR_HOST_UNREACHABLE_ERROR;
1451             break;
1452         case EINPROGRESS:
1453             prError = PR_IN_PROGRESS_ERROR;
1454             break;
1455         case EINTR:
1456             prError = PR_PENDING_INTERRUPT_ERROR;
1457             break;
1458         case EINVAL:
1459             prError = PR_INVALID_ARGUMENT_ERROR;
1460             break;
1461         case EIO:
1462             prError = PR_IO_ERROR;
1463             break;
1464         case EISCONN:
1465             prError = PR_IS_CONNECTED_ERROR;
1466             break;
1467         case EISDIR:
1468             prError = PR_IS_DIRECTORY_ERROR;
1469             break;
1470         case ELOOP:
1471             prError = PR_LOOP_ERROR;
1472             break;
1473         case EMFILE:
1474             prError = PR_PROC_DESC_TABLE_FULL_ERROR;
1475             break;
1476         case EMLINK:
1477             prError = PR_MAX_DIRECTORY_ENTRIES_ERROR;
1478             break;
1479         case EMSGSIZE:
1480             prError = PR_INVALID_ARGUMENT_ERROR;
1481             break;
1482 #ifdef EMULTIHOP
1483         case EMULTIHOP:
1484             prError = PR_REMOTE_FILE_ERROR;
1485             break;
1486 #endif
1487         case ENAMETOOLONG:
1488             prError = PR_NAME_TOO_LONG_ERROR;
1489             break;
1490         case ENETUNREACH:
1491             prError = PR_NETWORK_UNREACHABLE_ERROR;
1492             break;
1493         case ENFILE:
1494             prError = PR_SYS_DESC_TABLE_FULL_ERROR;
1495             break;
1496         /*
1497          * On SCO OpenServer 5, ENOBUFS is defined as ENOSR.
1498          */
1499 #if defined(ENOBUFS) && (ENOBUFS != ENOSR)
1500         case ENOBUFS:
1501             prError = PR_INSUFFICIENT_RESOURCES_ERROR;
1502             break;
1503 #endif
1504         case ENODEV:
1505             prError = PR_FILE_NOT_FOUND_ERROR;
1506             break;
1507         case ENOENT:
1508             prError = PR_FILE_NOT_FOUND_ERROR;
1509             break;
1510         case ENOLCK:
1511             prError = PR_FILE_IS_LOCKED_ERROR;
1512             break;
1513 #ifdef ENOLINK
1514         case ENOLINK:
1515             prError = PR_REMOTE_FILE_ERROR;
1516             break;
1517 #endif
1518         case ENOMEM:
1519             prError = PR_OUT_OF_MEMORY_ERROR;
1520             break;
1521         case ENOPROTOOPT:
1522             prError = PR_INVALID_ARGUMENT_ERROR;
1523             break;
1524         case ENOSPC:
1525             prError = PR_NO_DEVICE_SPACE_ERROR;
1526             break;
1527 #ifdef ENOSR
1528         case ENOSR:
1529             prError = PR_INSUFFICIENT_RESOURCES_ERROR;
1530             break;
1531 #endif
1532         case ENOTCONN:
1533             prError = PR_NOT_CONNECTED_ERROR;
1534             break;
1535         case ENOTDIR:
1536             prError = PR_NOT_DIRECTORY_ERROR;
1537             break;
1538         case ENOTSOCK:
1539             prError = PR_NOT_SOCKET_ERROR;
1540             break;
1541         case ENXIO:
1542             prError = PR_FILE_NOT_FOUND_ERROR;
1543             break;
1544         case EOPNOTSUPP:
1545             prError = PR_NOT_TCP_SOCKET_ERROR;
1546             break;
1547 #ifdef EOVERFLOW
1548         case EOVERFLOW:
1549             prError = PR_BUFFER_OVERFLOW_ERROR;
1550             break;
1551 #endif
1552         case EPERM:
1553             prError = PR_NO_ACCESS_RIGHTS_ERROR;
1554             break;
1555         case EPIPE:
1556             prError = PR_CONNECT_RESET_ERROR;
1557             break;
1558 #ifdef EPROTO
1559         case EPROTO:
1560             prError = PR_IO_ERROR;
1561             break;
1562 #endif
1563         case EPROTONOSUPPORT:
1564             prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
1565             break;
1566         case EPROTOTYPE:
1567             prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
1568             break;
1569         case ERANGE:
1570             prError = PR_INVALID_METHOD_ERROR;
1571             break;
1572         case EROFS:
1573             prError = PR_READ_ONLY_FILESYSTEM_ERROR;
1574             break;
1575         case ESPIPE:
1576             prError = PR_INVALID_METHOD_ERROR;
1577             break;
1578         case ETIMEDOUT:
1579             prError = PR_IO_TIMEOUT_ERROR;
1580             break;
1581 #if EWOULDBLOCK != EAGAIN
1582         case EWOULDBLOCK:
1583             prError = PR_WOULD_BLOCK_ERROR;
1584             break;
1585 #endif
1586         case EXDEV:
1587             prError = PR_NOT_SAME_DEVICE_ERROR;
1588             break;
1589         default:
1590             prError = PR_UNKNOWN_ERROR;
1591             break;
1592     }
1593     PR_SetError(prError, err);
1594 }
1595 
1596 static PRStatus
1597 nspr_bio_getpeername(PRFileDesc *fd, PRNetAddr *addr)
1598 {
1599     BIO *bio = nspr_get_bio(fd);
1600     int osfd;
1601     int ret;
1602     PRUint32 addrlen;
1603 
1604     if (!bio) {
1605         return -1;
1606     }
1607     ret = bio->m->ctrl(bio, BIO_C_GET_PEERNAME, sizeof(PRNetAddr), addr);
1608     if (ret > 0) {
1609 	return PR_SUCCESS;
1610     }
1611 
1612     ret = bio->m->ctrl(bio, BIO_C_GET_FD, sizeof(osfd), &osfd);
1613     if (ret <= 0) {
1614 	PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
1615 	return PR_FAILURE;
1616     }
1617     ret = getpeername(osfd, (struct sockaddr *) addr, &addrlen);
1618     if (ret < 0) {
1619 	npsr_map_error(errno);
1620     }
1621 
1622     return ret == 0 ? PR_SUCCESS : PR_FAILURE;
1623 }
1624 
1625 
1626 static PRStatus
1627 nspr_bio_close(PRFileDesc *fd)
1628 {
1629    BIO *bio = nspr_get_bio(fd);
1630 
1631    if (!bio) {
1632         return PR_FAILURE;
1633    }
1634 
1635    nspr_set_bio(fd, NULL);
1636    bio->m->destroy(bio);
1637    PR_Free(bio);
1638    return PR_SUCCESS;
1639 }
1640 
1641 static void
1642 ssl_init_bio()
1643 {
1644     const PRIOMethods *defaultMethods;
1645     gBioIdentity = PR_GetUniqueIdentity("NSS_COMPAT_OSSL_BIO_Layer");
1646     if (gIdentity == PR_INVALID_IO_LAYER) {
1647 //        log("Failed to init NSS stub layer");
1648     }
1649 
1650     defaultMethods = PR_GetDefaultIOMethods();
1651     if (defaultMethods == NULL) {
1652 //        log("Failed to init NSS stub layer");
1653     }
1654 
1655     /* Our layer has few methods. We use it for storage only */
1656     gBioMethods = *defaultMethods;
1657     gBioMethods.write = nspr_bio_write;
1658     gBioMethods.read = nspr_bio_read;
1659     gBioMethods.close = nspr_bio_close;
1660     gBioMethods.send = nspr_bio_send;
1661     gBioMethods.recv = nspr_bio_recv;
1662     gBioMethods.getpeername = nspr_bio_getpeername;
1663 }
1664 
1665 void SSL_load_error_strings(void)
1666 {
1667    /* NOOP */
1668 }
1669 
1670 int SSL_read(SSL *ssl, void *buf, int sz)
1671 {
1672     int rv;
1673     int flags;
1674     ossl_ctx_t *ossl;
1675 
1676     if (ssl) {
1677         ossl = nss_get_private(ssl);
1678         flags = SSL_get_shutdown(ssl);
1679 
1680         /* The SSL connection has been shut down */
1681         if (flags & SSL_RECEIVED_SHUTDOWN) {
1682             ossl->error = SSL_ERROR_ZERO_RETURN;
1683             return 0;
1684         }
1685     }
1686 
1687     rv = PR_Read(ssl, buf, sz);
1688 
1689     return rv;
1690 }
1691 
1692 int SSL_write(SSL *ssl, const void *buf, int num)
1693 {
1694     int rv;
1695     int flags;
1696     ossl_ctx_t *ossl;
1697 
1698     /* If SSL is not enabled then PR_Write will do the right thing */
1699     if (ssl) {
1700         ossl = nss_get_private(ssl);
1701         flags = SSL_get_shutdown(ssl);
1702 
1703         /* The SSL connection has been shut down */
1704         if (flags & SSL_SENT_SHUTDOWN) {
1705             ossl->error = SSL_ERROR_ZERO_RETURN;
1706             return 0;
1707         }
1708     }
1709 
1710     rv = PR_Write(ssl, buf, num);
1711 
1712     return rv;
1713 }
1714 
1715 SSL_METHOD *create_context(PRBool ssl2, PRBool ssl3, PRBool tlsv1,
1716                            PRBool server)
1717 {
1718     PRFileDesc *s = NULL;
1719     PRFileDesc *layer;
1720     ossl_ctx_t *ossl;
1721     int i;
1722 
1723     if (PR_TRUE != NSS_IsInitialized()) {
1724         PR_SetError(SEC_ERROR_NOT_INITIALIZED, 0);
1725         goto error;
1726     }
1727 
1728     /* Create socket -- used as template */
1729     s = PR_NewTCPSocket();
1730 
1731     /* Stick our storage layer in */
1732     layer = PR_CreateIOLayerStub(gIdentity, &gMethods);
1733     if (layer == NULL)
1734         goto error;
1735     if (PR_PushIOLayer(s, PR_TOP_IO_LAYER, layer) != PR_SUCCESS)
1736         goto error;
1737 
1738     s = SSL_ImportFD(NULL, s);
1739     if (s == NULL)
1740         goto error;
1741 
1742     /* Initialize the storage structure in our storage layer */
1743     ossl = new_ossl(NULL);
1744     ossl->server = server;
1745 
1746     nss_set_private(s, (PRFilePrivate *)ossl);
1747 
1748     if (SSL_OptionSet(s, SSL_SECURITY, PR_TRUE) != SECSuccess)
1749         goto error;
1750 
1751     if (SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, !server) != SECSuccess)
1752         goto error;
1753 
1754     if (SSL_OptionSet(s, SSL_HANDSHAKE_AS_SERVER, server) != SECSuccess)
1755         goto error;
1756 
1757     /* Don't fail if enabling SSL2 options doesn't succeed as it may
1758      * be disabled in NSS. So just ignore the return value from
1759      * SSL_OptionSet().
1760      */
1761     SSL_OptionSet(s, SSL_ENABLE_SSL2, ssl2);
1762     SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, ssl2);
1763 
1764     if (SSL_OptionSet(s, SSL_ENABLE_SSL3, ssl3)  != SECSuccess)
1765         goto error;
1766 
1767     if (SSL_OptionSet(s, SSL_ENABLE_TLS,  tlsv1) != SECSuccess)
1768         goto error;
1769 
1770     /* Set up callbacks for use by clients */
1771     if (!server) {
1772         if (SSL_OptionSet(s, SSL_NO_CACHE, PR_TRUE) != SECSuccess)
1773             goto error;
1774 
1775         if (SSL_BadCertHook(s, (SSLBadCertHandler)BadCertHandler, NULL)
1776          != SECSuccess)
1777             goto error;
1778     }
1779 
1780     /* Callback for authenticating certificate */
1781     if (SSL_AuthCertificateHook(s, AuthCertificateHandler, CERT_GetDefaultCertDB()) != SECSuccess)
1782             goto error;
1783 
1784     /* Disable all ciphers */
1785     for (i = 0; i < SSL_NumImplementedCiphers; i++)
1786     {
1787         SSL_CipherPrefSet(s, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
1788     }
1789 
1790     /* Enable the ones we want on by default */
1791     for (i = 0; i < SSL_NumImplementedCiphers; i++)
1792     {
1793         SSLCipherSuiteInfo suite;
1794         PRBool enabled;
1795 
1796         if (SSL_GetCipherSuiteInfo(ciphers_def[i].num, &suite, sizeof suite)
1797             == SECSuccess)
1798         {
1799             enabled = ciphers_def[i].enabled;
1800             if (enabled == SSL_ALLOWED)
1801             {
1802                 if (PK11_IsFIPS() && !suite.isFIPS)
1803                     enabled = SSL_NOT_ALLOWED;
1804             }
1805             SSL_CipherPrefSet(s, ciphers_def[i].num, enabled);
1806         }
1807     }
1808 
1809     return (s);
1810 
1811     error:
1812         if (s)
1813             PR_Close(s);
1814 
1815     return (NULL);
1816 }
1817 
1818 SSL_METHOD *SSLv2_client_method(void)
1819 {
1820     return create_context(PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
1821 }
1822 
1823 SSL_METHOD *SSLv23_client_method(void)
1824 {
1825     return create_context(PR_TRUE, PR_TRUE, PR_TRUE, PR_FALSE);
1826 }
1827 
1828 SSL_METHOD *SSLv3_client_method(void)
1829 {
1830     return create_context(PR_FALSE, PR_TRUE, PR_FALSE, PR_FALSE);
1831 }
1832 
1833 SSL_METHOD *TLSv1_client_method(void)
1834 {
1835     return create_context(PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE);
1836 }
1837 
1838 SSL_METHOD *SSLv2_server_method(void)
1839 {
1840     return create_context(PR_TRUE, PR_FALSE, PR_FALSE, PR_TRUE);
1841 }
1842 
1843 SSL_METHOD *SSLv23_server_method(void)
1844 {
1845     return create_context(PR_TRUE, PR_TRUE, PR_TRUE, PR_TRUE);
1846 }
1847 
1848 SSL_METHOD *SSLv3_server_method(void)
1849 {
1850     return create_context(PR_FALSE, PR_TRUE, PR_FALSE, PR_TRUE);
1851 }
1852 
1853 SSL_METHOD *TLSv1_server_method(void)
1854 {
1855     return create_context(PR_FALSE, PR_FALSE, PR_TRUE, PR_TRUE);
1856 }
1857 
1858 SSL_CTX *SSL_CTX_new(SSL_METHOD *passed)
1859 {
1860     /* real work done in SSL*_method() */
1861     return passed;
1862 }
1863 
1864 void SSL_CTX_free(SSL_CTX *ssl)
1865 {
1866     ossl_ctx_t *ossl;
1867 
1868     if (ssl) {
1869         ossl = nss_get_private(ssl);
1870         free_ossl(ossl);
1871         PR_Close(ssl);
1872     }
1873 }
1874 
1875 long SSL_CTX_set_timeout(SSL_CTX *ssl, long tm)
1876 {
1877     ossl_ctx_t *ossl;
1878     int prev;
1879 
1880     if (tm < 0)
1881         return 0;
1882 
1883     if (ssl) {
1884         ossl = nss_get_private(ssl);
1885 
1886         if (ossl->session_timeout != -1) {
1887             /* The cache is already initialized, shut it down */
1888             SSL_ShutdownServerSessionIDCache();
1889             prev = ossl->session_timeout;
1890         } else
1891             prev = DEF_SSL3_TIMEOUT;
1892 
1893         SSL_ConfigServerSessionIDCache(0, tm, tm, NULL);
1894         ossl->session_timeout = tm;
1895 
1896         return prev;
1897     }
1898 
1899     return 0; /* with no context this is really undefined */
1900 }
1901 
1902 /*
1903  * return 1 if any cipher could be selected and 0 on complete failure.
1904  */
1905 int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
1906 {
1907     int cipher_state[ciphernum];
1908     int rv, i;
1909     PRBool client = PR_FALSE;
1910 
1911     if (!ctx)
1912         return 0;
1913 
1914     rv = nss_parse_ciphers(str, cipher_state);
1915 
1916     if (rv) {
1917         /* First disable everything */
1918         for (i = 0; i < SSL_NumImplementedCiphers; i++)
1919             SSL_CipherPrefSet(ctx, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
1920 
1921         if (SSL_OptionGet(ctx, SSL_HANDSHAKE_AS_CLIENT, &client) != SECSuccess)
1922             return 0; /* failure */
1923 
1924         /* Need to be careful here. We can't rely on the return value
1925          * of nss_parse_ciphers() to determine if this call is succesful
1926          * or not. Since we touch the allowed ciphers we need to
1927          * re-calculate whether any ciphers were enabled.
1928          */
1929         rv = 0;
1930 
1931         /* Now enable what was requested */
1932         for (i=0; i<ciphernum; i++) {
1933             SSLCipherSuiteInfo suite;
1934             PRBool enabled;
1935 
1936             if (SSL_GetCipherSuiteInfo(ciphers_def[i].num, &suite, sizeof suite)
1937                 == SECSuccess)
1938             {
1939                 enabled = cipher_state[i] < 0 ? 0 : cipher_state[i];
1940                 /* nss_parse_ciphers() may return ciphers that are not
1941                  * allowed in our context, don't set them.
1942                  */
1943                 if (ciphers_def[i].client_only && !client) {
1944                     enabled = SSL_NOT_ALLOWED;
1945                 }
1946                 if (enabled == SSL_ALLOWED)
1947                 {
1948                     if (PK11_IsFIPS() && !suite.isFIPS)
1949                         enabled = SSL_NOT_ALLOWED;
1950                     else {
1951                         rv = 1;
1952                     }
1953                 }
1954                 SSL_CipherPrefSet(ctx, ciphers_def[i].num, enabled);
1955             }
1956         }
1957     }
1958 
1959     return rv;
1960 }
1961 
1962 /* API for OpenSSL statistics */
1963 
1964 long SSL_CTX_sess_number(SSL_CTX *s)
1965 {
1966     return 0;
1967 }
1968 
1969 long SSL_CTX_sess_connect(SSL_CTX *s)
1970 {
1971     return 0;
1972 }
1973 
1974 long SSL_CTX_sess_connect_good(SSL_CTX *s)
1975 {
1976     return 0;
1977 }
1978 
1979 long SSL_CTX_sess_connect_renegotiate(SSL_CTX *s)
1980 {
1981     return 0;
1982 }
1983 
1984 long SSL_CTX_sess_accept(SSL_CTX *s)
1985 {
1986     return 0;
1987 }
1988 
1989 long SSL_CTX_sess_accept_good(SSL_CTX *s)
1990 {
1991     return 0;
1992 }
1993 
1994 long SSL_CTX_sess_accept_renegotiate(SSL_CTX *s)
1995 {
1996     return 0;
1997 }
1998 
1999 long SSL_CTX_sess_hits(SSL_CTX *s)
2000 {
2001     return 0;
2002 }
2003 
2004 long SSL_CTX_sess_misses(SSL_CTX *s)
2005 {
2006     return 0;
2007 }
2008 
2009 long SSL_CTX_sess_timeouts(SSL_CTX *s)
2010 {
2011     return 0;
2012 }
2013 
2014 SSL *SSL_new(SSL_CTX *templ_s)
2015 {
2016     PRFileDesc *s;
2017     PRFileDesc *layer;
2018     ossl_ctx_t *ossl;
2019     ossl_ctx_t *ossl_templ;
2020 
2021     if (templ_s == NULL) {
2022         return NULL;
2023     }
2024 
2025     /* This layer contains the TCP/IP functions we need */
2026     s = PR_NewTCPSocket();
2027     if (s == NULL)
2028         return NULL;
2029 
2030     /* Stick our storage layer in */
2031     layer = PR_CreateIOLayerStub(gIdentity, &gMethods);
2032     if (layer == NULL)
2033         return NULL;
2034     if (PR_PushIOLayer(s, PR_TOP_IO_LAYER, layer) != PR_SUCCESS)
2035         return NULL;
2036 
2037     /* And finally add SSL on using the template passed in */
2038     s = SSL_ImportFD(templ_s, s);
2039 
2040     /* Initialize the storage structure in our storage layer */
2041     ossl = new_ossl(s);
2042 
2043     ossl_templ = nss_get_private(templ_s);
2044     ossl->server = ossl_templ->server;
2045     ossl->info_cb = ossl_templ->info_cb;
2046     ossl->verify_cb = ossl_templ->verify_cb;
2047     ossl->verify_mode = ossl_templ->verify_mode;
2048     ossl->nickname = ossl_templ->nickname;
2049     ossl->slotID = ossl_templ->slotID;
2050     ossl->slotname = ossl_templ->slotname;
2051 
2052     nss_set_private(s, (PRFilePrivate *)ossl);
2053 
2054     if (ossl->server && ossl->session_timeout == -1) {
2055         SSL_ConfigServerSessionIDCache(0, DEF_SSL2_TIMEOUT, DEF_SSL3_TIMEOUT, NULL);
2056         ossl->session_timeout = DEF_SSL3_TIMEOUT;
2057     }
2058 
2059     return s;
2060 }
2061 
2062 void SSL_free(SSL *ssl)
2063 {
2064     ossl_ctx_t *ossl;
2065 
2066     if (ssl) {
2067         ossl = nss_get_private(ssl);
2068         free_ossl(ossl);
2069 
2070         PR_Close(ssl);
2071     }
2072 }
2073 
2074 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
2075 {
2076     return SSL_CTX_use_certificate_chain_file(ctx, file);
2077 }
2078 
2079 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
2080 {
2081     ossl_ctx_t *ossl;
2082     int rv;
2083 
2084     if (!ctx)
2085         return 0;
2086 
2087     ossl = nss_get_private(ctx);
2088 
2089     /* FIXME: Load all certs in the file */
2090     if (ossl->server)
2091         rv = nss_set_server_cert(ctx, file, PR_FALSE);
2092     else
2093         rv = nss_set_client_cert(ctx, file);
2094 
2095     SSL_HandshakeCallback(ctx, (SSLHandshakeCallback)nss_HandshakeCallback, NULL);
2096 
2097     return rv;
2098 }
2099 
2100 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *filename, int type)
2101 {
2102 #ifdef PKCS11_PEM_MODULE
2103     ossl_ctx_t *ossl;
2104     PK11SlotInfo * slot = NULL;
2105     PK11GenericObject *rv;
2106     CK_ATTRIBUTE *attrs;
2107     CK_ATTRIBUTE theTemplate[20];
2108     CK_BBOOL cktrue = CK_TRUE;
2109     CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
2110     int retryCount = 0;
2111 #endif
2112 
2113     if (!ctx)
2114         return 0;
2115 
2116     /* It is probably empty because they are using the NSS database. */
2117     if (filename == NULL)
2118         return 1;
2119 
2120 #ifdef PKCS11_PEM_MODULE
2121     /* FIXME: grok the various file types */
2122 
2123     ossl = nss_get_private(ctx);
2124     if (!ossl) {
2125         return 0;
2126     }
2127 
2128     attrs = theTemplate;
2129 
2130     if (ossl->slotID == -1)
2131         ossl->slotID = slotCount++;
2132 
2133     /* May already exist if the cert is loaded */
2134     if (ossl->slotname == NULL) {
2135         ossl->slotname = PORT_ArenaAlloc(ossl->arena, 32);
2136         snprintf(ossl->slotname, 32, "PEM Token #%ld", ossl->slotID);
2137     }
2138 
2139     slot = PK11_FindSlotByName(ossl->slotname);
2140 
2141     if (!slot)
2142         return 0;
2143 
2144     PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
2145     PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
2146     PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)filename, strlen(filename)+1); attrs++;
2147 
2148     /* When adding an encrypted key the PKCS#11 will be set as removed */
2149     rv = PK11_CreateGenericObject(slot, theTemplate, 3, PR_FALSE /* isPerm */);
2150     if (rv == NULL) {
2151         PR_SetError(SEC_ERROR_BAD_KEY, 0);
2152         return 0;
2153     }
2154 
2155     /* This will force the token to be seen as re-inserted */
2156     SECMOD_WaitForAnyTokenEvent(pemMod, 0, 0);
2157     PK11_IsPresent(slot);
2158 
2159     if (PK11_Authenticate(slot, PR_TRUE, &retryCount) != SECSuccess) {
2160        return 0;
2161     }
2162 
2163     return 1;
2164 #else
2165     /* The key is already available if we're using the NSS database and not
2166      * the PEM-reading PKCS#11 module.
2167      */
2168     return 1;
2169 #endif
2170 }
2171 
2172 /*
2173  * We have to wait until the last minute to run this to be sure that all
2174  * CA certificates have been loaded.
2175  */
2176 int configureserver(SSL *ssl)
2177 {
2178     ossl_ctx_t *ossl;
2179     CERTCertificate *servercert;
2180     SSLKEAType KEAtype;
2181     SECKEYPrivateKey  *serverkey;
2182     PK11SlotInfo * slot = NULL;
2183 
2184     ossl = nss_get_private(ssl);
2185     if (!ossl) {
2186         return 0;
2187     }
2188 
2189     if (ossl->slotname) {
2190         /* Go ahead and re-create this to be sure we have the right slot */
2191         snprintf(ossl->slotname, 32, "PEM Token #%ld", ossl->slotID);
2192         slot = PK11_FindSlotByName(ossl->slotname);
2193     } else
2194         slot = PK11_GetInternalKeySlot();
2195 
2196     if (slot == NULL) {
2197         PR_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND, 0);
2198         return 0;
2199     }
2200 
2201     servercert = FindServerCertFromNickname(ossl->nickname);
2202 
2203     if (servercert == NULL) {
2204         PR_SetError(SEC_ERROR_UNKNOWN_CERT, 0);
2205         return 0;
2206     }
2207 
2208     serverkey = PK11_FindPrivateKeyFromCert(slot, servercert, NULL);
2209 
2210     if (serverkey == NULL) {
2211         PR_SetError(SEC_ERROR_NO_KEY, 0);
2212         return 0;
2213     }
2214 
2215     KEAtype = NSS_FindCertKEAType(servercert);
2216 
2217     if (SSL_ConfigSecureServer(ssl, servercert, serverkey, KEAtype) !=
2218          SECSuccess) {
2219 //        log("SSL error configuring server: '%s'", file);
2220         return 0;
2221     }
2222 
2223     CERT_DestroyCertificate(servercert);
2224     SECKEY_DestroyPrivateKey(serverkey);
2225 
2226     return 1;
2227 }
2228 
2229 int SSL_CTX_check_private_key(const SSL_CTX *ctx)
2230 {
2231     /* FIXME: What can we check here? */
2232     return 1; /* success */
2233 }
2234 
2235 STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
2236 {
2237     return 0;
2238 }
2239 
2240 void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
2241 {
2242 }
2243 
2244 void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
2245 {
2246 }
2247 
2248 X509 *SSL_get_certificate(SSL *ssl)
2249 {
2250     CERTCertificate *cert = NULL;
2251     X509 *x;
2252 
2253     if (ssl)
2254         cert = SSL_LocalCertificate(ssl);
2255 
2256     x = (X509 *)malloc(sizeof(X509));
2257 
2258     x->cert = cert;
2259 
2260     /* This arena/memory pool is used for allocating attributes of the
2261      * certificate such as dates, etc. */
2262     x->arena = PORT_NewArena(1024); /* This size is arbitrary */
2263 
2264     return x;
2265 }
2266 
2267 X509 *SSL_get_peer_certificate(SSL *ssl)
2268 {
2269     CERTCertificate *cert = NULL;
2270     X509 *x;
2271 
2272     if (ssl)
2273         cert = SSL_PeerCertificate(ssl);
2274 
2275     if (cert == NULL)
2276 	return NULL;
2277 
2278     x = (X509 *)malloc(sizeof(X509));
2279 
2280     x->cert = cert;
2281     x->arena = PORT_NewArena(1024); /* This size is arbitrary */
2282 
2283     return x;
2284 }
2285 
2286 X509 *d2i_X509(void *reserved, unsigned char **data, int len)
2287 {
2288     CERTCertificate *cert = NULL;
2289     SECItem derCert;
2290     CERTCertDBHandle *handle;
2291     X509 *x;
2292 
2293     handle = CERT_GetDefaultCertDB();
2294     derCert.data = *data;
2295     derCert.len = len;
2296     cert = CERT_NewTempCertificate(handle, &derCert, NULL, PR_FALSE, PR_TRUE);
2297     if (!cert) {
2298         return NULL;
2299     }
2300 
2301     x = (X509 *)malloc(sizeof(X509));
2302 
2303     x->cert = cert;
2304 
2305     /* This arena/memory pool is used for allocating attributes of the
2306      * certificate such as dates, etc. */
2307     x->arena = PORT_NewArena(1024); /* This size is arbitrary */
2308 
2309     return x;
2310 }
2311 
2312 
2313 X509_NAME *X509_get_issuer_name(X509 *x)
2314 {
2315     if (x->cert) {
2316         return &x->cert->issuer;
2317     }
2318 
2319     return NULL;
2320 }
2321 
2322 X509_NAME *X509_get_subject_name(X509 *x)
2323 {
2324     if (x->cert) {
2325         return &x->cert->subject;
2326     }
2327 
2328     return NULL;
2329 }
2330 
2331 void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
2332 {
2333     /* FIXME: stub */
2334     return NULL;
2335 }
2336 
2337 ASN1_TIME *X509_get_notBefore(X509 *x)
2338 {
2339     PRExplodedTime   printableTime;
2340     char             timeString[256];
2341     PRTime           notBefore, notAfter;
2342     ASN1_TIME       *result;
2343 
2344     CERT_GetCertTimes(x->cert, &notBefore, &notAfter);
2345 
2346     PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
2347 
2348     PR_FormatTime(timeString, 256, "%y%m%d%H%M%SZ", &printableTime);
2349 
2350     result = PORT_ArenaAlloc(x->arena, sizeof(ASN1_TIME));
2351 
2352     result->type = V_ASN1_UTCTIME;
2353     result->length = strlen(timeString);
2354     result->data = (unsigned char *)PORT_ArenaStrdup(x->arena, timeString);
2355 
2356     return result;
2357 }
2358 
2359 ASN1_TIME *X509_get_notAfter(X509 *x)
2360 {
2361     PRExplodedTime   printableTime;
2362     char             timeString[256];
2363     PRTime           notBefore, notAfter;
2364     ASN1_TIME       *result;
2365 
2366     CERT_GetCertTimes(x->cert, &notBefore, &notAfter);
2367 
2368     PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
2369 
2370     PR_FormatTime(timeString, 256, "%y%m%d%H%M%SZ", &printableTime);
2371 
2372     result = PORT_ArenaAlloc(x->arena, sizeof(ASN1_TIME));
2373 
2374     result->type = V_ASN1_UTCTIME;
2375     result->length = strlen(timeString);
2376     result->data = (unsigned char *)PORT_ArenaStrdup(x->arena, timeString);
2377 
2378     return result;
2379 }
2380 
2381 ASN1_INTEGER *X509_get_serialNumber(X509 *x)
2382 {
2383     ASN1_TIME *result;
2384 
2385     result = PORT_ArenaAlloc(x->arena, sizeof(ASN1_TIME));
2386 
2387     result->type = V_ASN1_INTEGER;
2388     result->length = x->cert->serialNumber.len;
2389     result->data = x->cert->serialNumber.data;
2390 
2391     return result;
2392 }
2393 
2394 /*
2395  * convert a byte buffer into an array of longs.
2396  */
2397 static void
2398 load_words(unsigned long *words, int len, unsigned char *bytes, int blen)
2399 {
2400 
2401     /*
2402      * the first word may have an odd number of bytes. we know this from
2403      * blen. */
2404     *words = 0;
2405     switch (blen % 4) {
2406     case 0:
2407         break;
2408     case 3:
2409         *words = ((unsigned long) *bytes) << 16;
2410         bytes++;
2411     case 2:
2412         *words |= ((unsigned long) *bytes) << 8;
2413         bytes++;
2414     case 1:
2415         *words |= (unsigned long) *bytes;
2416         bytes++;
2417         words++; len--;
2418         break;
2419     }
2420     /* at this point the rest of the bytes are a multiple of 4, crank through
2421      * them */
2422     while (len > 0) {
2423         *words++ = (((unsigned long)bytes[0]) << 24) |
2424                    (((unsigned long)bytes[1]) << 16) |
2425                    (((unsigned long)bytes[2]) << 8) |
2426                    (((unsigned long)bytes[3]) << 16);
2427         len--; bytes += 4;
2428     }
2429 }
2430 
2431 /*
2432  * helper function to divide 2 longs by a long. This function only works if
2433  * div <= 0xffff, and high is < 0xffff. remander will always be less than div
2434  * (and thus less than 0xffff) */
2435 static unsigned long
2436 longdiv(unsigned long high, unsigned long low, unsigned long div,
2437                 unsigned long *premainder)
2438 {
2439     unsigned long temp, remainder, result;
2440     if (high == 0) {
2441         result = low/div;
2442         *premainder = low % div;
2443         return result;
2444     }
2445     /* safe because the upper half of high is always zero */
2446     temp = ((high << 16) | (low >> 16));
2447     /* result is going to be less than 0xffff because high is always less
2448      * then div, which means temp is less than div*0x10000 */
2449     result = temp/div;
2450     remainder = temp % div;
2451     /* again, temp/div is less than 0xffff because remainder is less than div */
2452     temp = ((remainder << 16) | (low & 0xffff));
2453     *premainder = temp % div;
2454     result = result << 16;
2455     return result | temp/div;
2456 }
2457 
2458 /*
2459  * divide an array by a number. NOTE: div must be less that 0xffff
2460  */
2461 static unsigned long
2462 div_words(unsigned long **pwords, int *plen, unsigned long div)
2463 {
2464     unsigned long remainder = 0;
2465     unsigned long result;
2466     unsigned long *words=*pwords;
2467     int len = *plen;
2468     int i;
2469 
2470     for (i=0; i < len; i++) {
2471         result = longdiv(remainder, words[i], div, &remainder);
2472         words[i] = result;
2473     }
2474     while ((*words == 0) && len > 0) {
2475         words++; len--;
2476     }
2477     *pwords = words;
2478     *plen = len;
2479 
2480     return remainder;
2481 }
2482 
2483 char *i2s_ASN1_INTEGER(void *reserved, ASN1_INTEGER *asn1Int)
2484 {
2485     /* output an integer as a decimal value */
2486     unsigned long decimal_result;
2487     unsigned long *words, *space;
2488     unsigned long power10=10000; /* power of ten less than 0x10000 */
2489     int len = (asn1Int->length + (sizeof(unsigned long)-1))
2490                 /sizeof(unsigned long);
2491     int bufLen;
2492     char *buf, *result;
2493 
2494     space = words = PORT_NewArray(unsigned long, len);
2495     bufLen = len*8*4+1; /* definitely big enough */
2496     buf = PORT_Alloc(bufLen);
2497     buf[bufLen-1] = 0;
2498     bufLen -= 1;
2499 
2500     load_words(words, len, asn1Int->data, asn1Int->length);
2501 
2502     while (len > 0) {
2503         char tmpbuf[5];
2504             decimal_result = div_words(&words, &len, power10);
2505         sprintf(tmpbuf,"%04d",(int)decimal_result);
2506         memcpy(&buf[bufLen-4],tmpbuf, 4); /* loose the terminating null */
2507         bufLen -= 4;
2508     }
2509     /* drop leading zeros */
2510     while (buf[bufLen] == '0') {
2511         bufLen++;
2512     }
2513     /* special case '0' */
2514     if (buf[bufLen] == 0) {
2515         bufLen--;
2516     }
2517     /* return a properly aligned and freeable string to the user */
2518     result = PORT_Strdup(&buf[bufLen]);
2519 
2520     PORT_Free(space);
2521     PORT_Free(buf);
2522     return result;
2523 }
2524 
2525 char *X509_NAME_oneline(X509_NAME *x, char *s, int len)
2526 {
2527     char *value = NULL;
2528 
2529     if (!x)
2530         return NULL;
2531 
2532     value = CERT_NameToAscii(x);
2533 
2534     if (s)
2535         s = PL_strncpyz(s, value, len);
2536     else
2537         s = PORT_ArenaStrdup(x->arena, value);
2538 
2539     return s;
2540 }
2541 
2542 void X509_free(X509 *x)
2543 {
2544     if (x->cert)
2545         CERT_DestroyCertificate(x->cert);
2546     if (x->arena)
2547         PORT_FreeArena(x->arena, PR_FALSE);
2548     free(x);
2549 }
2550 
2551 /* Not thread-safe */
2552 const char *X509_verify_cert_error_string(long n)
2553 {
2554     return nss_error(n);
2555 }
2556 
2557 int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
2558 {
2559     switch (nid)
2560     {
2561         case NID_commonName:
2562             strncpy(buf, CERT_GetCommonName(name), len);
2563             break;
2564         default:
2565             strncpy(buf, "Unknown", len);
2566             break;
2567     }
2568     return 0;
2569 }
2570 
2571 SSL_CIPHER *SSL_get_current_cipher(SSL *s)
2572 {
2573     return s;
2574 }
2575 
2576 int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits)
2577 {
2578     int on, keySize, secretKeySize;
2579     char *cipher, *issuer, *subject;
2580     SECStatus secstatus = SECFailure;
2581 
2582     if (!c)
2583         return 0;
2584 
2585     secstatus = SSL_SecurityStatus((PRFileDesc *)c, &on, &cipher,
2586                                    &keySize, &secretKeySize, &issuer,
2587                                    &subject);
2588 
2589     if (secstatus != SECSuccess)
2590         return 0;
2591 
2592     if (alg_bits != NULL)
2593         *alg_bits = keySize;
2594 
2595     return secretKeySize;
2596 }
2597 
2598 char *SSL_CIPHER_get_version(SSL_CIPHER *cipher)
2599 {
2600     return SSL_get_version(cipher);
2601 }
2602 
2603 void SSL_CIPHER_description(SSL_CIPHER *c, char *s, int len)
2604 {
2605     SSLChannelInfo      channel;
2606     SSLCipherSuiteInfo  suite;
2607 
2608     if (SSL_GetChannelInfo(c, &channel, sizeof channel) ==
2609         SECSuccess && channel.length == sizeof channel &&
2610         channel.cipherSuite)
2611     {
2612         if (SSL_GetCipherSuiteInfo(channel.cipherSuite,
2613             &suite, sizeof suite) == SECSuccess)
2614         {
2615             /* The space here is because stunnel plays with the string */
2616             snprintf(s, len, "%s ", suite.cipherSuiteName);
2617         }
2618     }
2619     return;
2620 }
2621 
2622 const char *SSL_CIPHER_get_name(SSL_CIPHER *c)
2623 {
2624     SSLChannelInfo      channel;
2625     SSLCipherSuiteInfo  suite;
2626     char                buf[128];
2627     ossl_ctx_t         *ossl;
2628 
2629     ossl = nss_get_private(c);
2630 
2631     if (SSL_GetChannelInfo(c, &channel, sizeof channel) ==
2632         SECSuccess && channel.length == sizeof channel &&
2633         channel.cipherSuite)
2634     {
2635         if (SSL_GetCipherSuiteInfo(channel.cipherSuite,
2636             &suite, sizeof suite) == SECSuccess)
2637         {
2638             /* The space here is because stunnel plays with the string */
2639             snprintf(buf, 128, "%s ", suite.cipherSuiteName);
2640         }
2641     }
2642 
2643     return PORT_ArenaStrdup(ossl->arena, buf);
2644 }
2645 
2646 int SSL_get_shutdown(SSL *ssl)
2647 {
2648     ossl_ctx_t *ossl;
2649 
2650     if (!ssl)
2651         return 0;
2652 
2653     ossl = nss_get_private(ssl);
2654 
2655     return ossl->shutdown_flags;
2656 }
2657 
2658 PRStatus SSL_set_shutdown(SSL *ssl, int flags)
2659 {
2660     int both = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
2661     PRStatus status = PR_SUCCESS;
2662     ossl_ctx_t *ossl;
2663 
2664     if (!ssl)
2665         return 0; /* returns no diagnostic info */
2666 
2667     ossl = nss_get_private(ssl);
2668     ossl->shutdown_flags = flags;
2669 
2670     if ((flags & both) == both)
2671         status = PR_Shutdown(ssl, PR_SHUTDOWN_BOTH);
2672 
2673     else if ((flags & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN)
2674         status = PR_Shutdown(ssl, PR_SHUTDOWN_SEND);
2675 
2676     else if ((flags & SSL_RECEIVED_SHUTDOWN) == SSL_RECEIVED_SHUTDOWN)
2677         status = PR_Shutdown(ssl, PR_SHUTDOWN_RCV);
2678 
2679     return 0; /* returns no diagnostic info */
2680 }
2681 
2682 char *SSL_get_version(SSL *ssl)
2683 {
2684     SSLChannelInfo      channel;
2685     SSLCipherSuiteInfo  suite;
2686     ossl_ctx_t         *ossl;
2687     char               *protocol = NULL;
2688 
2689     if (!ssl)
2690         return "unknown";
2691 
2692     ossl = nss_get_private(ssl);
2693 
2694     if (SSL_GetChannelInfo(ssl, &channel, sizeof channel) ==
2695         SECSuccess && channel.length == sizeof channel &&
2696         channel.cipherSuite) {
2697         if (SSL_GetCipherSuiteInfo(channel.cipherSuite,
2698                                 &suite, sizeof suite) == SECSuccess) {
2699             switch (channel.protocolVersion) {
2700                 case SSL_LIBRARY_VERSION_2:
2701                     protocol = PORT_ArenaStrdup(ossl->arena, "SSLv2");
2702                     break;
2703                 case SSL_LIBRARY_VERSION_3_0:
2704                     protocol = PORT_ArenaStrdup(ossl->arena, "SSLv3");
2705                     break;
2706                 case SSL_LIBRARY_VERSION_3_1_TLS:
2707                     protocol = PORT_ArenaStrdup(ossl->arena, "TLSv1");
2708                     break;
2709             }
2710         }
2711     }
2712 
2713     return protocol;
2714 }
2715 
2716 int SSL_set_session(SSL *to, SSL_SESSION *session)
2717 {
2718     return -1;
2719 }
2720 
2721 int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
2722         const char *CApath)
2723 {
2724     int         rv = 1;
2725 #ifdef PKCS11_PEM_MODULE
2726     struct stat st;
2727     PRDir      *dir;
2728     PRDirEntry *entry;
2729 #endif
2730 
2731     if (!ctx)
2732         return 0;
2733 
2734     if (CAfile != NULL)
2735         rv = nss_set_server_cert(ctx, CAfile, PR_TRUE);
2736 
2737 #ifdef PKCS11_PEM_MODULE
2738     if (CApath == NULL)
2739         return rv;
2740 
2741     if (stat(CApath, &st) == -1)
2742         return -1;
2743 
2744     if (S_ISDIR(st.st_mode)) {
2745         dir = PR_OpenDir(CApath);
2746         int rv;
2747         do {
2748             entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN);
2749 
2750             if (entry) {
2751                 char fullpath[1024];
2752 
2753                 snprintf(fullpath, 1024, "%s/%s", CApath, entry->name);
2754                 rv = nss_set_server_cert(ctx, fullpath, PR_TRUE);
2755             }
2756         /* This is purposefully tolerant of errors so non-PEM files
2757          * can be in the same directory */
2758         } while (entry != NULL);
2759     }
2760 
2761     PR_CloseDir(dir);
2762 #endif
2763 
2764     return rv;
2765 }
2766 
2767 int SSL_CTX_set_default_verify_paths(SSL_CTX * ctx) {
2768     if (PR_FALSE == SECMOD_HasRootCerts()) {
2769         char configstring[64];
2770 
2771         /* try to load root certs module */
2772         PR_snprintf(configstring, 64, "library=%s name=\"Root Certs\" parameters=\"\"", root_certs_library);
2773         rootMod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
2774         if (rootMod || !rootMod->loaded) {
2775             SECMOD_DestroyModule(rootMod);
2776             rootMod = NULL;
2777         }
2778     }
2779 }
2780 
2781 void SSL_set_verify(SSL *ssl, int mode,
2782                     int (*callback)(int ok, X509_STORE_CTX *ctx))
2783 {
2784 #if 0
2785     ossl_ctx_t * ossl = NULL;
2786     if (!ssl)
2787         return;
2788 
2789     ossl = nss_get_private((SSL *)ssl);
2790 
2791     ossl->verify_mode = mode;
2792     /* FIXME: save the callback fn */
2793 
2794     return;
2795 #endif
2796     return SSL_CTX_set_verify(ssl, mode, callback);
2797 }
2798 
2799 void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
2800                         int (*callback)(int ok, X509_STORE_CTX *))
2801 {
2802     ossl_ctx_t * ossl = NULL;
2803     if (!ctx)
2804         return;
2805 
2806     ossl = nss_get_private((SSL *)ctx);
2807 
2808     /* The NSS tuning knobs for verification are server-only. But we
2809      * will save the mode for use in BadCertHandler(). */
2810     if (!ossl->server)
2811         goto done;
2812 
2813     /* According to the man page, mode should either be SSL_VERIFY_NONE
2814      * or SSL_VERIFY_PEER (which may be modified). So lets check for
2815      * either of those first and punt if neither is found.
2816      */
2817 
2818     if (mode == SSL_VERIFY_NONE) {
2819         /* On the off-chance that this function is called twice, go ahead and
2820          * turn off all verification rather than assuming it is already off.
2821          */
2822         SSL_OptionSet(ctx, SSL_REQUEST_CERTIFICATE, PR_FALSE);
2823         SSL_OptionSet(ctx, SSL_REQUIRE_CERTIFICATE, PR_FALSE);
2824         return;
2825     }
2826 
2827     if (!(mode & SSL_VERIFY_PEER)) return;
2828 
2829     /* SSL_VERIFY_PEER - request certificate */
2830     SSL_OptionSet(ctx, SSL_REQUEST_CERTIFICATE, PR_TRUE);
2831     SSL_OptionSet(ctx, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NO_ERROR); /* ensures a full handshake */
2832 
2833     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
2834         SSL_OptionSet(ctx, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_ALWAYS);
2835 
2836     if (mode & SSL_VERIFY_CLIENT_ONCE)
2837         SSL_OptionSet(ctx, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_FIRST_HANDSHAKE);
2838 
2839 done:
2840     ossl->verify_mode = mode;
2841     ossl->verify_cb = callback;
2842 
2843     return;
2844 }
2845 
2846 long SSL_get_verify_result(const SSL *ssl)
2847 {
2848     ossl_ctx_t * ossl = NULL;
2849     if (!ssl)
2850         return -1;
2851 
2852     ossl = nss_get_private((SSL *)ssl);
2853 
2854     return ossl->verify_result;
2855 }
2856 
2857 void CRYPTO_free(void *data)
2858 {
2859     if (data)
2860         PORT_Free(data);
2861 }
2862 
2863 void CRYPTO_cleanup_all_ex_data(void)
2864 {
2865 }
2866 
2867 /*
2868  * Set the native file descriptor for use in the SSL connection.
2869  */
2870 int SSL_set_fd(SSL *s, int fd)
2871 {
2872     PRFileDesc *new;
2873 
2874     /* Close the original handle created by PR_NewTCPSocket() so we don't
2875      * leak fds.
2876      */
2877     close(PR_FileDesc2NativeHandle(s));
2878 
2879     /* Grab the NSPR layer and replace the file descriptor */
2880     new = PR_GetIdentitiesLayer(s, PR_NSPR_IO_LAYER);
2881     PR_ChangeFileDescNativeHandle(new, fd);
2882 
2883     return 1;
2884 }
2885 /*
2886  * Set the native file descriptor for use in the SSL connection.
2887  */
2888 int SSL_set_bio(SSL *s, BIO *bio, BIO *bio1)
2889 {
2890     PRFileDesc *old;
2891     PRFileDesc *new;
2892 
2893     if (bio != bio1) {
2894         return -1;
2895     }
2896 
2897 
2898     if (gBioIdentity == PR_INVALID_IO_LAYER) {
2899         ssl_init_bio();
2900     }
2901 
2902     /* close the previous layer */
2903     old = PR_GetIdentitiesLayer(s, gBioIdentity);
2904     if (old) {
2905 	PR_PopIOLayer(s, gBioIdentity);
2906         old->dtor(old);
2907     }
2908 
2909     /* Stick our storage layer in */
2910     new = PR_CreateIOLayerStub(gBioIdentity, &gBioMethods);
2911     if (new == NULL)
2912         goto error;
2913     nspr_set_bio(new , bio);
2914     if (PR_PushIOLayer(s, PR_GetLayersIdentity(s->lower), new) != PR_SUCCESS)
2915         goto error;
2916 
2917     return 1;
2918 
2919 error:
2920     return -1;
2921 }
2922 
2923 BIO *
2924 BIO_new(BIO_METHOD *bm)
2925 {
2926    BIO *bio;
2927 
2928    bio = PR_NEW(BIO);
2929    if (!bio) {
2930         return NULL;
2931    }
2932    bio->m = bm;
2933    bm->create(bio);
2934    return bio;
2935 }
2936 
2937 int BIO_clear_retry_flags(BIO *b)
2938 {
2939    return 0;
2940 }
2941 
2942 int BIO_set_retry_read(BIO *b)
2943 {
2944    return 0;
2945 }
2946 
2947 int BIO_set_retry_write(BIO *b)
2948 {
2949    return 0;
2950 }
2951 
2952 
2953 int SSL_set_rfd(SSL *ssl, int fd)
2954 {
2955     return -1;
2956 }
2957 
2958 int SSL_set_wfd(SSL *ssl, int fd)
2959 {
2960     return -1;
2961 }
2962 
2963 int SSL_set_ex_data(SSL *ssl, int idx, void *data)
2964 {
2965     ossl_ctx_t * ossl;
2966 
2967     if (ssl) {
2968         ossl = nss_get_private(ssl);
2969         if (PL_HashTableAdd(ossl->appdata, (void *)idx, (void *)data))
2970             return 0;
2971         else
2972             return -1; /* man page is unclear what to return on error */
2973     }
2974     return -1;
2975 }
2976 
2977 void *SSL_get_ex_data(const SSL *ssl, int idx)
2978 {
2979     ossl_ctx_t * ossl;
2980     void * rval = NULL;
2981 
2982     if (ssl) {
2983         ossl = nss_get_private((SSL *)ssl);
2984         rval = PL_HashTableLookup(ossl->appdata, (void *)idx);
2985     }
2986 
2987     return NULL;
2988 }
2989 
2990 int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
2991                                          unsigned int sid_ctx_len)
2992 {
2993     return 0;
2994 }
2995 
2996 void SSL_set_connect_state(SSL *s)
2997 {
2998     /* NOOP */
2999 }
3000 
3001 void SSL_set_accept_state(SSL *s)
3002 {
3003     /* NOOP */
3004 }
3005 
3006 int SSL_accept(SSL *ssl)
3007 {
3008     PRPollDesc pollset[2];
3009 
3010     if (!configureserver(ssl))
3011         return 0;
3012 
3013     SSL_ResetHandshake(ssl, PR_TRUE); /* reset as server */
3014 
3015     /* Force the handshake */
3016     pollset[0].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
3017     pollset[0].out_flags = 0;
3018     pollset[0].fd = ssl;
3019     while(1)
3020     {
3021         PRStatus status;
3022         PRInt32 filesReady;
3023 
3024         SSL_ForceHandshake(ssl);
3025         filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
3026         if (filesReady < 0) {
3027             goto error;
3028         }
3029         if (filesReady == 0) { /* shouldn't happen! */
3030             goto error;
3031         }
3032         status = PR_ConnectContinue(ssl, pollset[0].out_flags);
3033         if (status == PR_SUCCESS)
3034             break;
3035         if (PR_GetError() != PR_IN_PROGRESS_ERROR)
3036             goto error;
3037     }
3038 
3039     error:
3040 
3041     return 1;
3042 }
3043 
3044 int SSL_connect(SSL *ssl)
3045 {
3046     if (SSL_ResetHandshake(ssl, PR_FALSE /* reset as client */) !=
3047         SECSuccess)
3048         return 0;
3049 
3050     /* Make the handshake happen now */
3051     if (SSL_ForceHandshake(ssl) == SECSuccess)
3052         return 1;
3053     else
3054         return 0;
3055 }
3056 
3057 int SSL_pending(SSL *ssl)
3058 {
3059     /* Never any data pending. NSS does this behind the scenes. */
3060     return 0;
3061 }
3062 
3063 int SSL_shutdown(SSL *ssl)
3064 {
3065     PRStatus status;
3066     ossl_ctx_t *ossl;
3067 
3068     if (!ssl)
3069         return -1;
3070 
3071     ossl = nss_get_private(ssl);
3072     ossl->shutdown_flags = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
3073 
3074     status = PR_Shutdown(ssl, PR_SHUTDOWN_BOTH);
3075 
3076     /* We don't want to PR_Close() it here */
3077 
3078     if (status == PR_SUCCESS)
3079         return 1;
3080     else
3081         return -1;
3082 }
3083 
3084 int SSL_want(SSL *s)
3085 {
3086     /* I read this as: there is SSL data to operate on, not user data.
3087      * If this is the case then this will always be zero as NSS
3088      * hides this detail.
3089      */
3090 
3091     return SSL_NOTHING;
3092 }
3093 
3094 int SSL_peek(SSL *ssl, void *buf, int num)
3095 {
3096     int flags;
3097 
3098     if (ssl) {
3099         flags = SSL_get_shutdown(ssl);
3100         if (flags & SSL_RECEIVED_SHUTDOWN)
3101             return 0;
3102     }
3103 
3104     /* FIXME: Timeout should not be hardcoded */
3105     return PR_Recv(ssl, buf, num, PR_MSG_PEEK, PR_SecondsToInterval(1));
3106 }
3107 
3108 int SSL_get_error(SSL *ssl, int i)
3109 {
3110     if (ssl) {
3111         ossl_ctx_t *ossl = nss_get_private(ssl);
3112         if (ossl && ossl->error)
3113             return ossl->error;
3114     }
3115 
3116     return PR_GetError();
3117 }
3118 
3119 SSL_SESSION *SSL_get_session(SSL *ssl)
3120 {
3121     /* NSS manages sessions for us */
3122     return NULL;
3123 }
3124 
3125 void SSL_SESSION_free(SSL_SESSION *sess)
3126 {
3127     return;
3128 }
3129 
3130 #if 0
3131 int ENGINE_init(ENGINE *);
3132 
3133 void ENGINE_register_all_complete(void);
3134 
3135 int ENGINE_set_default(ENGINE *, int);
3136 
3137 ENGINE *ENGINE_by_id(const char *);
3138 
3139 int ENGINE_ctrl_cmd_string(ENGINE *, const char *, const char *, const char *);
3140 
3141 void ENGINE_finish(ENGINE *);
3142 void ENGINE_free(ENGINE *);
3143 #endif
3144 
3145 #define ERR_GET_REASON(l)       (int)((l)&0xfffL)
3146 unsigned long ERR_get_error(void)
3147 {
3148     long err;
3149 
3150     err = PR_GetError();
3151     /* OpenSSL has a stack of errors. We provide just one, so clear it out */
3152     PR_SetError(0, 0);
3153     return err;
3154 }
3155 
3156 unsigned long ERR_peek_error(void)
3157 {
3158     return PR_GetError();
3159 }
3160 
3161 unsigned long ERR_peek_last_error(void)
3162 {
3163     return PR_GetError();
3164 }
3165 
3166 void ERR_remove_state(unsigned long pid)
3167 {
3168     return; /* NSS has no queue to free */
3169 }
3170 
3171 char *ERR_error_string_n(unsigned long e, char *buf, size_t len)
3172 {
3173     PL_strncpyz(buf, nss_error(e), len);
3174     return buf;
3175 }
3176 
3177 /* Not thread-safe */
3178 char *ERR_error_string(unsigned long e, char *buf)
3179 {
3180     static char errbuf[256]; /* 256 is arbitrary */
3181     if (buf) {
3182         /* FIXME: ack, how do we know how long buf is?  */
3183         ERR_error_string_n(e, buf, 256);
3184         return buf;
3185     } else {
3186         ERR_error_string_n(e, errbuf, 256);
3187         return errbuf;
3188     }
3189 }
3190 
3191 void ERR_free_strings(void)
3192 {
3193     return;
3194 }
3195 
3196 void EVP_cleanup(void)
3197 {
3198     return;
3199 }
3200 
3201 const char *SSL_alert_type_string_long(int value)
3202 {
3203     return (NULL);
3204 }
3205 
3206 const char *SSL_alert_desc_string_long(int value)
3207 {
3208     return (NULL);
3209 }
3210 
3211 const char *SSL_state_string_long(const SSL *s)
3212 {
3213     /* We have no visibility into the current NSS handshake state */
3214     return "Unknown";
3215 }
3216 
3217 void SSL_CTX_set_info_callback(SSL_CTX *ctx, void(*cb)())
3218 {
3219     ossl_ctx_t *ossl;
3220 
3221     if (!ctx)
3222         return;
3223 
3224     ossl = nss_get_private(ctx);
3225 
3226     ossl->info_cb = cb;
3227 
3228     return;
3229 }
3230 
3231 /* SSL_*ctrl */
3232 long SSL_CTX_set_options(SSL_CTX *c, long i)
3233 {
3234   return 0;
3235 }
3236 
3237 long SSL_CTX_set_session_cache_mode(SSL_CTX *c, long i)
3238 {
3239   return 0;
3240 }
3241 
3242 long SSL_CTX_set_mode(SSL_CTX *ctx, long mode)
3243 {
3244     return 0;
3245 }
3246 
3247 void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
3248 {
3249     /* FIXME: should we call this or not? */
3250     return;
3251 }
3252 
3253 void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
3254 {
3255     /* FIXME: save the data sent */
3256     return;
3257 }
3258 
3259 /* SSL_CTX_set_default_passwd_cb* is ignored */
3260 int PEM_def_callback(char *buf, int num, int w, void *key)
3261 {
3262     *buf = 0;
3263     return 0;
3264 }
3265 
3266 long SSL_session_reused(SSL *s)
3267 {
3268   return 0;
3269 }
3270 
3271 X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
3272 {
3273     return ctx->current_cert;
3274 }
3275 
3276 #define X509_STORE_CTX_EX_DATA_SSL_IDX 42
3277 int SSL_get_ex_data_X509_STORE_CTX_idx(void)
3278 {
3279     return X509_STORE_CTX_EX_DATA_SSL_IDX;
3280 }
3281 
3282 void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
3283 {
3284     if (idx == X509_STORE_CTX_EX_DATA_SSL_IDX)
3285 	return ctx->ssl__;
3286     return NULL;
3287 }
3288 
3289 
3290 int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
3291 			      X509_OBJECT *ret)
3292 {
3293     PRArenaPool *arena;
3294     CERTCertificate * cert;
3295     SECItem *subject;
3296 
3297     (void)vs;
3298     if (type != X509_LU_X509)
3299 	return 0;
3300 
3301     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
3302     if (arena == NULL)
3303 	return 0;
3304     subject = SEC_ASN1EncodeItem(arena, NULL, name, CERT_NameTemplate);
3305     cert = NULL;
3306     if (subject != NULL)
3307 	cert = CERT_FindCertByName(CERT_GetDefaultCertDB(), subject);
3308     PORT_FreeArena(arena, PR_FALSE);
3309     if (cert == NULL)
3310 	return 0;
3311     /* FIXME: a more useful representation of the certificate, e.g. one that
3312        does not leak? */
3313     ret->type = siBuffer;
3314     ret->data = (unsigned char *)cert;
3315     ret->len = sizeof (*cert);
3316     return 1;
3317 }
3318 
3319 
3320 void CRYPTO_set_id_callback(unsigned long (*func)(void))
3321 {
3322 }
3323 
3324 void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
3325 					      const char *file, int line))
3326 {
3327 }
3328 
3329 int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
3330         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
3331     /* FIXME: need to handle the 3 functions as well */
3332     return ex_data_index++;
3333 }
3334 
3335 unsigned char * ASN1_STRING_data(ASN1_STRING *x)
3336 {
3337     return x->data;
3338 }
3339 
3340 int ASN1_STRING_type(ASN1_STRING *x)
3341 {
3342     return x->type;
3343 }
3344 
3345 int ASN1_STRING_length(ASN1_STRING *x)
3346 {
3347     return x->length;
3348 }
3349