]> Repositorios git - scryer-prolog.git/commitdiff
Merge branch 'js/rustls' into js/integration
authorJavier Sagredo <[email protected]>
Tue, 16 Jun 2026 22:38:06 +0000 (00:38 +0200)
committerJavier Sagredo <[email protected]>
Tue, 16 Jun 2026 22:38:06 +0000 (00:38 +0200)
1  2 
src/lib/tls.pl
src/machine/system_calls.rs

diff --cc src/lib/tls.pl
index c317857c819599e627f84e62000928e0b7280696,f974accd03f398d21d289ce6b07d88465f732c69..9e15d3017b1496e09e1997bd422bb9215a754714
@@@ -49,66 -47,62 +50,73 @@@ tls_client_context(tls_context(Host), O
  tls_client_negotiate(tls_context(Host), S0, S) :-
          '$tls_client_connect'(Host, S0, S).
  
 -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -   TLS Servers
 -   ===========
 -
 -   Use tls_server_context/2 to create a TLS context, for example with:
 -
 -   tls_server_context(Context, [certificate(Cert),key(Key)])
 -
 -   where Cert is a list of characters with the contents of a
 -   PEM-encoded certificate chain, and Key is a list of characters with
 -   the contents of the corresponding PEM-encoded private key. The
 -   private key may be in PKCS #8, PKCS #1 (RSA) or SEC1 (EC) format.
 -
 -   The certificate chain should contain a leaf certificate followed by
 -   any intermediate certificates that should be sent to clients to
 -   allow them to build a chain to a trusted root. The chain
 -   certificates should be in order from the leaf certificate towards
 -   the root.
 -
 -   You can use phrase_from_file/3 from library(pio) and seq//1 from
 -   library(dcgs) to read the contents of "cert.pem" and "key.pem" into
 -   strings:
 -
 -   phrase_from_file(seq(Cert), "cert.pem"), phrase_from_file(seq(Key), "key.pem")
 -
 -   The obtained context should be treated as an opaque Prolog term.
 -
 -   Using the context and an existing stream S0 (for example, the
 -   result of socket_server_accept/4), a TLS stream S can be negotiated
 -   by a Prolog-based server with:
 -
 -   tls_server_negotiate(Context, S0, S)
 -
 -   S will be an encrypted and authenticated stream with the client.
 -
 -   The advantage of separating the creation of the server context from
 -   negotiating a connection is that the context can be created only
 -   once, and quickly cloned for every incoming connection. This is
 -   currently not implemented: In the present implementation, a new context
 -   is created for every connection, using the specified parameters.
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 -
 +%% tls_server_context(-Context, +Options)
 +%
 +% Use `tls_server_context/2` to create a TLS context, for example with:
 +%
 +% ```
- % tls_server_context(Context, [pkcs12(Chars)])
++% tls_server_context(Context, [certificate(Cert),key(Key)])
 +% ```
 +%
- % where Chars is a list of characters with the contents of a DER-formatted PKCS
- % #12 archive. The option `password(Ps)` can be used to specify the password
- % `Ps` (also a string) for decrypting the key.  On some versions of OSX, and
- % potentially also on other platforms, empty passwords are not supported.
++% where `Cert` is a list of characters with the contents of a PEM-encoded
++% certificate chain, and `Key` is a list of characters with the contents of the
++% corresponding PEM-encoded private key. The private key may be in PKCS #8, PKCS
++% #1 (RSA) or SEC1 (EC) format.
 +%
- % The archive should contain a leaf certificate and its private key, as well any
- % intermediate certificates that should be sent to clients to allow them to
- % build a chain to a trusted root. The chain certificates should be in order
- % from the leaf certificate towards the root.
++% The certificate chain should contain a leaf certificate followed by any
++% intermediate certificates that should be sent to clients to allow them to build
++% a chain to a trusted root. The chain certificates should be in order from the
++% leaf certificate towards the root.
 +%
- % PKCS #12 archives typically have the file extension `.p12` or `.pfx`, and can
- % be created with the OpenSSL `pkcs12` tool:
++% You can use `phrase_from_file/3` from `library(pio)` and `seq//1` from `library(dcgs)`
++% to read the contents of "cert.pem" and "key.pem" into strings:
 +%
 +% ```
- % $ openssl pkcs12 -export -out identity.pfx \
- %                  -inkey key.pem -in cert.pem -certfile chain_certs.pem
- % ```
- %
- % You can use `phrase_from_file/3` from `library(pio)` and `seq//1` from
- % `library(dcgs)` to read the contents of `identity.pfx` into a string:
- %
- % ```
- % phrase_from_file(seq(Chars), "identity.pfx", [type(binary)])
++% phrase_from_file(seq(Cert), "cert.pem"), phrase_from_file(seq(Key), "key.pem")
 +% ```
 +%
 +% The obtained context should be treated as an opaque Prolog term.
- tls_server_context(tls_context(Cert,Password), Options) :-
-         (   member(pcks12(Cert), Options) ->
+ tls_server_context(tls_context(Cert,Key), Options) :-
+         (   member(certificate(Cert), Options) ->
              must_be(chars, Cert)
-         ;   domain_error(contains_pcks12, Options, tls_server_context/2)
+         ;   domain_error(contains_certificate, Options, tls_server_context/2)
          ),
-         (   member(password(Password), Options) ->
-             must_be(chars, Password)
-         ;   Password = ""
+         (   member(key(Key), Options) ->
+             must_be(chars, Key)
+         ;   domain_error(contains_key, Options, tls_server_context/2)
          ).
  
- %% tls_server_negotiate(+Context, +Stream0, -Stream)
++%% tls_server_negotiate(+Context, +Stream0, -Stream, +Options)
 +%
 +% Using the context and an existing stream `S0` (for example, the result of
 +% `socket_server_accept/4`), a TLS stream `S` can be negotiated by a
 +% Prolog-based server with:
 +%
 +% ```
- % tls_server_negotiate(Context, S0, S)
++% tls_server_negotiate(Context, S0, S, Options)
 +% ```
 +%
 +% `S` will be an encrypted and authenticated stream with the client.
 +%
++% Currently, the only existing option is `client_certificate(Cert)` where `Cert`
++% will be unified with the client certificate if the client provides one, or the
++% atom `none` if none is provided. To get the client certificate, use `Options =
++% [client_certificate(Cert)]`.
++%
 +% The advantage of separating the creation of the server context from
 +% negotiating a connection is that the context can be created only once, and
 +% quickly cloned for every incoming connection. This is currently not
 +% implemented: In the present implementation, a new context is created for every
 +% connection, using the specified parameters.
- tls_server_negotiate(tls_context(Cert,Password), S0, S) :-
-         '$tls_accept_client'(Cert, Password, S0, S).
++tls_server_negotiate(tls_context(Cert,Key), S0, S, Options) :-
++    must_be(list, Options),
++    ( member(client_certificate(ClientCert), Options) ->
++      '$tls_accept_client'(Cert, Key, S0, S, ClientCert)
++    ; '$tls_accept_client'(Cert, Key, S0, S, _)
++    ).
++
++%% tls_server_negotiate(+Context, +Stream0, -Stream)
++%
++% Like `tls_server_negotiate/4` with empty options.
+ tls_server_negotiate(Ctx, S0, S) :-
+     tls_server_negotiate(Ctx, S0, S, []).
 -
 -tls_server_negotiate(tls_context(Cert,Key), S0, S, Options) :-
 -    member(client_certificate(ClientCert), Options) ->
 -    '$tls_accept_client'(Cert, Key, S0, S, ClientCert)
 -    ; '$tls_accept_client'(Cert, Key, S0, S, _).
Simple merge