Skip to content

Commit b5918e1

Browse files
committed
HACK: NSS Support
1 parent 4be368b commit b5918e1

File tree

2 files changed

+134
-1
lines changed

2 files changed

+134
-1
lines changed

configure

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ External library support:
203203
--enable-libxavs enable AVS encoding via xavs [no]
204204
--enable-libxvid enable Xvid encoding via xvidcore,
205205
native MPEG-4/Xvid encoder exists [no]
206+
--enable-nss enable NSS [no]
206207
--enable-openssl enable openssl [no]
207208
--enable-x11grab enable X11 grabbing [no]
208209
--enable-zlib enable zlib [autodetect]
@@ -1055,6 +1056,7 @@ EXTERNAL_LIBRARY_LIST="
10551056
libx264
10561057
libxavs
10571058
libxvid
1059+
nss
10581060
openssl
10591061
x11grab
10601062
zlib
@@ -1819,7 +1821,7 @@ sctp_protocol_deps="struct_sctp_event_subscribe"
18191821
sctp_protocol_select="network"
18201822
srtp_protocol_select="rtp_protocol"
18211823
tcp_protocol_select="network"
1822-
tls_protocol_deps_any="openssl gnutls"
1824+
tls_protocol_deps_any="openssl gnutls nss"
18231825
tls_protocol_select="tcp_protocol"
18241826
udp_protocol_select="network"
18251827

@@ -3569,6 +3571,7 @@ enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 &&
35693571
die "ERROR: libx264 version must be >= 0.118."; }
35703572
enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs
35713573
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
3574+
enabled nss && require_pkg_config nss nss.h NSS_Init
35723575
enabled openssl && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
35733576
check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
35743577
check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||

libavformat/tls.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@
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+
7098
static 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;
196326
fail:

0 commit comments

Comments
 (0)