4646 if (c->ctx) \
4747 SSL_CTX_free(c->ctx); \
4848 } while (0)
49+ #elif CONFIG_NSS
50+ #include <nspr.h>
51+ #include <nss.h>
52+ #include <prinit.h>
53+ #include <prio.h>
54+ #include <private/pprio.h>
55+ #include <prnetdb.h>
56+ #include <ssl.h>
57+ #define TLS_read (c , buf , size ) PR_Read(c->nssfd, buf, size)
58+ #define TLS_write (c , buf , size ) PR_Write(c->nssfd, buf, size)
59+ #define TLS_shutdown (c ) PR_Close(c->nssfd)
60+ #define TLS_free (c ) do { \
61+ if (c->nssai) \
62+ PR_FreeAddrInfo(c->nssai); \
63+ } while (0)
4964#endif
5065#include "network.h"
5166#include "os_support.h"
@@ -63,10 +78,23 @@ typedef struct {
6378#elif CONFIG_OPENSSL
6479 SSL_CTX * ctx ;
6580 SSL * ssl ;
81+ #elif CONFIG_NSS
82+ PRAddrInfo * nssai ;
83+ PRFileDesc * nssfd ;
84+ PRStatus cstatus ;
85+ SECStatus status ;
6686#endif
6787 int fd ;
6888} TLSContext ;
6989
90+ #if CONFIG_NSS
91+ static SECStatus nss_auth_cert_hook (void * arg , PRFileDesc * socket ,
92+ PRBool checksig , PRBool isserver )
93+ {
94+ return SECSuccess ;
95+ }
96+ #endif
97+
7098static int do_tls_poll (URLContext * h , int ret )
7199{
72100 TLSContext * c = h -> priv_data ;
@@ -90,6 +118,22 @@ static int do_tls_poll(URLContext *h, int ret)
90118 av_log (h , AV_LOG_ERROR , "%s\n" , ERR_error_string (ERR_get_error (), NULL ));
91119 return AVERROR (EIO );
92120 }
121+ #elif CONFIG_NSS
122+ PRPollDesc prdesc ;
123+
124+ prdesc .fd = c -> nssfd ;
125+ prdesc .in_flags = PR_POLL_READ | PR_POLL_WRITE ;
126+
127+ ret = PR_Poll (& prdesc , 1 , PR_INTERVAL_NO_TIMEOUT );
128+ if (ret < 1 ) {
129+ av_log (h , AV_LOG_ERROR , "Cannot poll.\n" );
130+ return AVERROR (EIO );
131+ }
132+
133+ if (prdesc .out_flags & PR_POLL_READ )
134+ p .events = POLLIN ;
135+ else if (prdesc .out_flags & PR_POLL_WRITE )
136+ p .events = POLLOUT ;
93137#endif
94138 if (h -> flags & AVIO_FLAG_NONBLOCK )
95139 return AVERROR (EAGAIN );
@@ -191,6 +235,92 @@ static int tls_open(URLContext *h, const char *uri, int flags)
191235 if ((ret = do_tls_poll (h , ret )) < 0 )
192236 goto fail ;
193237 }
238+ #elif CONFIG_NSS
239+ PR_Init (PR_USER_THREAD , PR_PRIORITY_NORMAL , 0 );
240+
241+ c -> status = NSS_NoDB_Init (NULL );
242+ if (c -> status != SECSuccess ) {
243+ av_log (h , AV_LOG_ERROR , "Cannot snitialize NSS.\n" );
244+ ret = AVERROR (EIO );
245+ goto fail ;
246+ }
247+
248+ c -> status = NSS_SetDomesticPolicy ();
249+ if (c -> status != SECSuccess ) {
250+ av_log (h , AV_LOG_ERROR , "Cannot initialize NSS ciphers.\n" );
251+ ret = AVERROR (EIO );
252+ goto fail ;
253+ }
254+
255+ c -> nssfd = SSL_ImportFD (NULL , PR_ImportTCPSocket (c -> fd ));
256+ if (!c -> nssfd ) {
257+ av_log (h , AV_LOG_ERROR , "Cannot import URL descriptor with NSS.\n" );
258+ ret = AVERROR (EIO );
259+ goto fail ;
260+ }
261+
262+ c -> status = SSL_OptionSet (c -> nssfd , SSL_SECURITY , PR_TRUE );
263+ if (c -> status != SECSuccess ) {
264+ av_log (h , AV_LOG_ERROR , "Cannot enable SSL security.\n" );
265+ ret = AVERROR (EIO );
266+ goto fail ;
267+ }
268+
269+ c -> status = SSL_OptionSet (c -> nssfd , SSL_HANDSHAKE_AS_CLIENT , PR_TRUE );
270+ if (c -> status != SECSuccess ) {
271+ av_log (h , AV_LOG_ERROR , "Cannot enable client-style handshake.\n" );
272+ ret = AVERROR (EIO );
273+ goto fail ;
274+ }
275+
276+ c -> status = SSL_AuthCertificateHook (c -> nssfd , nss_auth_cert_hook , NULL );
277+ if (c -> status != SECSuccess ) {
278+ av_log (h , AV_LOG_ERROR ,
279+ "Cannot register cetrificate auth callback function with NSS.\n" );
280+ ret = AVERROR (EIO );
281+ goto fail ;
282+ }
283+
284+ if (!numerichost ) {
285+ ret = SSL_SetURL (c -> nssfd , host );
286+ if (ret < 0 ) {
287+ av_log (h , AV_LOG_ERROR , "Cannot set hostname with NSS.\n" );
288+ goto fail ;
289+ }
290+ }
291+ /*
292+ c->nssai = PR_GetAddrInfoByName(host, PR_AF_INET, NULL); <-- wrong struct anyway
293+ if (!c->nssai) {
294+ av_log(h, AV_LOG_ERROR, "Could not get address info with NSS.\n");
295+ ret = AVERROR(EIO);
296+ goto fail
297+ }
298+
299+ c->cstatus = PR_Connect(c->nssfd, c->nssai, PR_INTERVAL_NO_TIMEOUT);
300+ if (c->cstatus != PR_SUCCESS) {
301+ av_log(h, AV_LOG_ERROR, "Could not create TLS/SSL session.\n");
302+ ret = AVERROR(EIO);
303+ goto fail;
304+ }*/
305+
306+ c -> status = SSL_ResetHandshake (c -> nssfd , PR_FALSE );
307+ if (c -> status != SECSuccess ) {
308+ av_log (h , AV_LOG_ERROR , "Cannot reset HandShake.\n" );
309+ ret = AVERROR (EIO );
310+ goto fail ;
311+ }
312+
313+ c -> status = SSL_ForceHandshake (c -> nssfd );
314+ if (c -> status != SECSuccess ) {
315+ av_log (h , AV_LOG_ERROR , "Could not negotiate TLS/SSL session.\n" );
316+ ret = AVERROR (EIO );
317+ goto fail ;
318+ }
319+
320+ // while(1) {
321+ // if ((ret = do_tls_poll(h, 0)) < 0)
322+ // goto fail;
323+ // }
194324#endif
195325 return 0 ;
196326fail :
0 commit comments