1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.libraries calendar combinators delegate
4 destructors io io.sockets io.sockets.private kernel memoize namespaces
5 openssl.libssl present sequences summary system vocabs ;
8 SYMBOL: secure-socket-timeout
10 1 minutes secure-socket-timeout set-global
12 SYMBOL: secure-socket-backend
14 HOOK: ssl-supported? secure-socket-backend ( -- ? )
15 HOOK: ssl-certificate-verification-supported? secure-socket-backend ( -- ? )
17 M: object ssl-supported? f ;
18 M: object ssl-certificate-verification-supported? f ;
20 SINGLETONS: TLSv1 TLSv1.1 TLSv1.2 ;
22 ERROR: no-tls-supported ;
24 MEMO: best-tls-method ( -- class )
26 { [ "TLSv1_2_method" "libssl" dlsym? ] [ TLSv1.2 ] }
27 { [ "TLSv1_1_method" "libssl" dlsym? ] [ TLSv1.1 ] }
28 { [ "TLSv1_method" "libssl" dlsym? ] [ TLSv1 ] }
41 : <secure-config> ( -- config )
43 best-tls-method >>method
44 1024 >>ephemeral-key-bits
45 ssl-certificate-verification-supported? >>verify ;
47 TUPLE: secure-context < disposable config handle ;
49 HOOK: <secure-context> secure-socket-backend ( config -- context )
51 : with-secure-context ( config quot -- )
53 [ <secure-context> ] [ [ secure-context set ] prepose ] bi*
58 { addrspec read-only }
59 { hostname read-only } ;
63 M: secure present addrspec>> present " (secure)" append ;
65 M: secure (server) addrspec>> (server) ;
67 CONSULT: inet secure addrspec>> ;
69 M: secure resolve-host
70 [ addrspec>> resolve-host ] [ hostname>> ] bi
71 [ <secure> ] curry map ;
73 HOOK: check-certificate secure-socket-backend ( host handle -- )
75 PREDICATE: secure-inet < secure addrspec>> inet? ;
79 M: secure-inet (client)
81 [ resolve-host (client) [ |dispose ] dip ] keep
82 addrspec>> host>> pick handle>> check-certificate
87 ERROR: premature-close ;
89 M: premature-close summary
90 drop "Connection closed prematurely - potential truncation attack" ;
92 ERROR: certificate-verify-error result ;
94 M: certificate-verify-error summary
95 drop "Certificate verification failed" ;
97 ERROR: subject-name-verify-error expected got ;
99 M: subject-name-verify-error summary
100 drop "Subject name verification failed" ;
102 ERROR: certificate-missing-error ;
104 M: certificate-missing-error summary
105 drop "Host did not present any certificate" ;
107 ERROR: upgrade-on-non-socket ;
109 M: upgrade-on-non-socket summary
111 "send-secure-handshake can only be used if input-stream and" print
112 "output-stream are a socket" ;
114 ERROR: upgrade-buffers-full ;
116 M: upgrade-buffers-full summary
118 "send-secure-handshake can only be used if buffers are empty" ;
120 HOOK: non-ssl-socket? os ( obj -- ? )
122 HOOK: socket-handle os ( obj -- ? )
124 HOOK: send-secure-handshake secure-socket-backend ( -- )
126 HOOK: accept-secure-handshake secure-socket-backend ( -- )
129 { [ os unix? ] [ "io.sockets.secure.unix" require ] }
130 { [ os windows? ] [ "io.sockets.secure.windows" require ] }