[comment {-*- tcl -*- doctools manpage}]
[manpage_begin "SSPI" n ""]
[copyright "2007-2013 Ashok P. Nadkarni"]
[moddesc "Security Service Provider Interface"]
[titledesc "Commands for invoking the Security Service Provider Interface"]
[require twapi_crypto]
[description]
[para]

[emph "This module is still experimental and liable to change."]

[para]
This package includes procedures related to the Security Service
Provider Interface (SSPI) on the Windows platforms. For commands
for other cryptographic operations, refer to the
[uri crypto.html "CryptoAPI"] documentation.

[section "SSPI overview"]

The Security Support Provider Interface is a standard interface to
various security protocols that provide for security functions such
as authentication, encryption and integrity. The SSPI interface allows
establishment of a security context that can be used for signing and
encrypting data passed between a client and a server.

[para]
This module currently supports only the 
[const Negotiate], [const NTLM], [const Kerberos], [const SChannel] and 
[const {Microsoft Unified Security Protocol Provider}] packages.

[section "SSPI security context establishment"]
On the client side, the application program starts off by retrieving
the credentials to be used to authenticate itself to the server by calling
[uri \#sspi_acquire_credentials [cmd sspi_acquire_credentials]] with
the [cmd "-role client"] option. It then creates a new client security
context by calling
[uri \#sspi_client_context [cmd sspi_client_context]]
specifying appropriate desired security characteristics. The application
then exchanges messages with the server to complete the authentication.

[para]
Depending on the security protocol in use, the authentication between
the client and the server may require multiple message exchanges between
the client and the server. Once it obtains its security context,
the client calls
[uri \#sspi_step [cmd sspi_step]]
passing it the security context. This command returns an indication
of whether the authentication is complete, or more exchanges with the
server are required. In the latter case, data returned by the command
is sent to the server and the server response is passed back to the
command. This sequence is repeated until the command indicates the
authentication is complete or generates a Tcl exception indicating
authentication failure. The security context generated in this
manner can then be used to sign and encrypt messages between
the client and the server.

[para]
On the server side, the application program starts off by retrieving
its own credentials by calling
[uri \#sspi_acquire_credentials [cmd sspi_acquire_credentials]] with
the [cmd "-role server"]. It then creates a new server security
context by calling
[uri \#sspi_server_context [cmd sspi_server_context]]
passing it the authentication data sent by the client. The server
then enters the authentication loop described below. From this point
on, the server follows the authentication loop calling
[uri \#sspi_step [cmd sspi_step]]
in the same manner as described above for the client.

[para]
Once a security context is established, either on the client or
the server, its characteristics, including the negotiated parameters,
security principal name etc. can be retrieved through
commands
[uri \#sspi_context_features [cmd sspi_context_features]],
[uri \#sspi_context_username [cmd sspi_context_username]]
and
[uri \#sspi_context_sizes [cmd sspi_context_sizes]].
In the case of SSL/SChannel based providers, the
[uri #sspi_local_cert [cmd sspi_local_cert]] and
[uri #sspi_remote_cert [cmd sspi_remote_cert]] return the certificates
in use for a connection.
Note that not all commands are supported by all security providers.

[para]
The security context should be released when
no longer needed. For schannel based providers only, first call
[uri #sspi_shutdown_context [cmd sspi_shutdown_context]] 
and pass any returned data to the remote peer. Then call
[uri \#sspi_delete_context [cmd sspi_delete_context]] to release
context releases. For other providers, only [cmd sspi_delete_context]
should be called.

[para] Similarly, when no longer required,
both the server and client ends should free
resources associated with their credentials by calling
[uri \#sspi_free_credentials [cmd sspi_free_credentials]].


[section "SSPI message signing and encryption"]
Once a security context has been completely created as above, it
can then be used to generate and verify messages signatures using
[uri \#sspi_sign [cmd sspi_sign]]
and
[uri \#sspi_verify_signature [cmd sspi_verify_signature]]
respectively.

[para]
Similarly, the security context can be used to encrypt and decrypt
messages using
[uri #sspi_encrypt [cmd sspi_encrypt]] and [uri #sspi_decrypt [cmd sspi_decrypt]].

[section "SSPI stream encryption"]
For SSPI stream contexts, the commands
[uri #sspi_encrypt_stream [cmd sspi_encrypt_stream]] and
[uri #sspi_decrypt_stream [cmd sspi_decrypt_stream]] encrypt and decrypt
streaming data. Alternately the 
[uri #sspi_encrypt_and_write [cmd sspi_encrypt_and_write]] command
can be used to directly write encrypted data to a channel.

[section Commands]

[list_begin definitions]

[call [cmd sspi_acquire_credentials] [opt [arg options]]]
Returns a credentials handle that can be used to negotiate and establish a
security context. The command returns the handle to the credentials
unless the [cmd -getexpiration] option is specified in which
case it returns a keyed list with two fields: [cmd -handle] which
is the handle to the credentials, and [cmd -expiration] which
returns the time (as number of 100ns intervals since January 1, 1601)
at which the credentials expire.

[nl]
The following options may be specified with the command:
[list_begin opt]

[opt_def [cmd -credentials] [arg CREDENTIALS]]
Specifies the credentials to which a handle is to be returned. If unspecified
the default credentials for the package are used. For NTLM or Negotiate
providers, the [uri #sspi_winnt_identity_credentials [cmd sspi_winnt_identity_credentials]]
should be used to return non-default credentials in the appropriate format.
For SSL/Schannel based providers, the
[uri #sspi_schannel_credentials [cmd sspi_schannel_credentials]]
should be used for the same purpose.

[opt_def [cmd -getexpiration]]
If specified, the expiration time for the returned credentials is also
returned. See description of command return value above.

[opt_def [cmd -package] [arg SECURITYPACKAGE]]
Specifies the security package with which the credentials are to
be used. By default, this is [const NTLM]. The list of available
security packages on a system can be obtained through
[uri \#sspi_enumerate_packages [cmd sspi_enumerate_packages]].

[opt_def [cmd -principal] [arg PRINCIPAL]]
Specifies the name of the principal whose credentials are to be
referenced. By default, this is the user account under which
the process is running.

[opt_def [cmd -role] [arg ROLE]]
Indicates how the credentials will be used, based on [arg ROLE] -
[const client] or [const outbound] for clients,
[const server] or [const inbound] for servers and
[const both] (default) if credentials are used for both purposes.
Note that SSL/SChannel based providers require separate client
and server credentials and [const both] is not a valid option for
them.

[list_end]

[nl]
The returned credentials handle must be freed by calling
[uri \#sspi_free_credentials [cmd sspi_free_credentials]]
when no longer needed.


[call [cmd sspi_client_context] [arg CREDENTIALS] [opt [arg options]]]
Initiates the building of a new client-side, security context from
based on the specified credentials. [arg CREDENTIALS] is a
handle to credentials returned by
[uri #sspi_acquire_credentials [cmd sspi_acquire_credentials]].
The returned value, which is a handle to a security context,
should be treated as opaque by the caller
and used as described in [sectref "SSPI security context establishment"].

[nl]
The options below specify the requirements for the context. Note that
not all security providers support all options or combinations of options.
Refer to the Windows SDK for more information about these options.

[list_begin opt]
[opt_def [cmd -confidentiality] [arg BOOL]]
If specified as [const true], messages are to be encrypted.

[opt_def [cmd -connection] [arg BOOL]]
If specified as [const true], the security context will not handle
formatting of messages.

[opt_def [cmd -datarep] [arg DATAREP]]
Specifies the data representation on the target. [arg DATAREP]
must be either [const network] (default) or [const native].

[opt_def [cmd -delegate] [arg BOOL]]
If specified as [const true], the server can use the context to
other servers as the client. Requires [cmd -mutualauth] to also
be specified as [const true].

[opt_def [cmd -extendederror] [arg BOOL]]
When [const true], the remote end is notified of errors. Note that
several Windows versions, including Windows 7, may experience SSL/TLS
negotiation failures
when this option is specified. See Microsoft Knowledgebase article KB975858
for details.

[opt_def [cmd -integrity] [arg BOOL]]
If specified as [const true], messages are to be signed.

[opt_def [cmd -manualvalidation] [arg BOOL]]
If [arg BOOL] is [const false] (default), SChannel based providers will
validate the remote server's certificate. If specified as [const true],
the provider will not validate the received certificate. It is the
caller's responsibility to do so. The remote certificate
can be retrieved with [uri #sspi_remote_cert [cmd sspi_remote_cert]]
and verified as described in [uri crypto.html#certificateverification "Certificate verification"].

[opt_def [cmd -mutualauth] [arg BOOL]]
If specified as [const true], both the client and server are
to be authenticated.

[opt_def [cmd -replaydetect] [arg BOOL]]
If specified as [const true], detection of replayed messages is desired.

[opt_def [cmd -sequencedetect] [arg BOOL]]
If specified as [const true], detection of out-of-sequence messages is desired.

[opt_def [cmd -stream] [arg BOOL]]
If specified as [const true], indicates a stream oriented connection.

[opt_def [cmd -target] [arg TARGET]]
Specifies the target of the security context. The format depends on the
security service provider. In the case of a SSL/SChannel based
provider, this is generally the name that should match
the subject name in the certificate sent by the server.

[opt_def [cmd -usesessionkey] [arg BOOL]]
If specified as [const true], a new session key must be negotiated.

[list_end]

[nl]
When a security context is no longer required, it should be released
by calling
[uri #sspi_delete_context [cmd sspi_delete_context]].

[call [cmd sspi_context_features] [arg CONTEXT]]
After a security context is established, this command may be
used to retrieve information about what security features were
negotiated. The command returns a keyed list with boolean values
for the following fields.
[list_begin opt]
[opt_def [cmd -confidentiality]]
If [const true], encryption is supported.

[opt_def [cmd -connection]]
If [const true], the security context will not handle
formatting of messages.

[opt_def [cmd -delegate]]
If [const true], the server can use the context to
other servers as the client.

[opt_def [cmd -extendederror]]
If [const true], the remote end is notified of errors.

[opt_def [cmd -integrity]]
If [const true], messages signing is supported.

[opt_def [cmd -mutualauth]]
If [const true], both the client and server are
authenticated.

[opt_def [cmd -replaydetect]]
If [const true], detection of replayed messages is enabled.

[opt_def [cmd -sequencedetect]]
If [const true], detection of out-of-sequence messages is enabled.

[opt_def [cmd -stream]]
If [const true], indicates a stream oriented connection.

[list_end]

[call [cmd sspi_context_sizes] [arg CONTEXT]]
Returns a keyed list with the following fields:
[list_begin opt]
[opt_def [cmd -maxtoken]]
Maximum size of token used in the authentication exchange.
[opt_def [cmd -maxsig]]
Maximum size of signature.
[opt_def [cmd -blocksize]]
Messages should preferably be a multiple of this value.
[opt_def [cmd -trailersize]]
Size of security trailer to be appended to messages.
[list_end]

[call [cmd sspi_context_username] [arg CONTEXT]]
[emph TBD]

[call [cmd sspi_decrypt] [arg CONTEXT] [arg ENCRYPTTOKEN] [arg ENCRYPTEDDATA] [arg PADDING] [opt [arg options]]]
Returns the decrypted data. [arg CONTEXT] is a datagram or connection
context. The other parameters correspond to the corresponding values
returned from [uri #sspi_encrypt [cmd sspi_encrypt]].

[call [cmd sspi_decrypt_stream] [arg CONTEXT] [arg ENCRYPTEDDATA]]
Returns the decrypted data using the specified stream context.
The return value is a pair consisting of a status and the decrypted
data. The status may be one of [const ok], [const expired],
or [const renegotiate]. In all cases the second element, if non empty,
contains the decrypted data.
[nl]
A status of [const ok] is a normal return. If the status is [const expired],
the context has expired and the caller should call
[uri #sspi_shutdown_context [cmd sspi_shutdown_context]] and
[uri #sspi_delete_context [cmd sspi_delete_context]] to free
the context.

[call [cmd sspi_delete_context] [arg CONTEXT]]
Closes a security context constructed through
[uri #sspi_client_context [cmd sspi_client_context]] or
[uri #sspi_server_context [cmd sspi_server_context]] or
and frees any associated resources.

[call [cmd sspi_encrypt] [arg CONTEXT] [arg BINDATA] [opt [arg options]]]
Encrypts the binary data [arg BINDATA] 
based on the specified security context. Returns
a list of three elements - the encryption token, the encrypted data
and padding. These must all be passed to the remote peer for it successfully
decrypt and verify the data.

[call [cmd sspi_encrypt_and_write] [arg CONTEXT] [arg BINDATA] [opt [arg options]]]
Encrypts binary data [arg BINDATA] based on the specified security context and
writes it to the specified channel. The channel must be in binary mode.

[call [cmd sspi_encrypt_stream] [arg CONTEXT] [arg BINDATA] [opt [arg options]]]
Encrypts [arg BINDATA] based on the specified security context and
returns the encrypted data.

[call [cmd sspi_enumerate_packages] [opt [arg options]]]
If no arguments are specified, 
returns a list of the names of the security provider packages available
on the system. If any options are specified, returns a dictionary
keyed by the package name. The corresponding value is itself a dictionary
with the keys dependent on the options specified to the command:

[list_begin opt]
[opt_def [cmd -all]] Same as all options being specified.
[opt_def [cmd -capabilities]] A list of tokens that describe the 
capabilties of the provider.
[opt_def [cmd -comment]] A comment describing the provider.
[opt_def [cmd -rpcid]] A DCE RPC identifier, if supported.
[opt_def [cmd -maxtokensize]] Maximum size of a security token.
[opt_def [cmd -name]] Name of the provider.
[opt_def [cmd -version]] The version of the provider interface.
[list_end]

[call [cmd sspi_free_credentials] arg CREDENTIALS]
Frees resources associated with credentials returned by
[uri \#sspi_acquire_credentials [cmd sspi_acquire_credentials]].

[call [cmd sspi_issuers_accepted_by_peer] [arg CONTEXT]]
For SChannel based client contexts, the remote server can request
a client certificate issued by specific certificate issuers it will accept.
This command returns the list of issuers acceptable to the remote server.

[call [cmd sspi_local_cert] [arg CONTEXT]]
Returns a certificate context for the certificate for the local end
of a secured connection. The returned certificate context
must be freed by calling [uri #cert_release [cmd cert_release]].

[call [cmd sspi_remote_cert] [arg CONTEXT]]
Returns a certificate context for the certificate sent by the remote
end of a secured connection. The returned certificate context
must be freed by calling [uri #cert_release [cmd cert_release]].

[call [cmd sspi_server_context] [arg CREDENTIALS] [arg CLIENTDATA] [opt [arg options]]]

Initiates the building of a new server-side, security context from
based on the specified credentials and security data received from
the client. [arg CREDENTIALS] is a
handle to credentials returned by
[uri #sspi_acquire_credentials [cmd sspi_acquire_credentials]].
The returned value, which is a handle to a security context,
should be treated as opaque by the caller
and used as described in [sectref "SSPI security context establishment"].

[nl]
The options below specify the requirements for the context. Note that
not all security providers support all options or combinations of options.
Refer to the Windows SDK for more information about these options.

[list_begin opt]
[opt_def [cmd -confidentiality] [arg BOOL]]
If specified as [const true], messages are to be encrypted.

[opt_def [cmd -connection] [arg BOOL]]
If specified as [const true], the security context will not handle
formatting of messages.

[opt_def [cmd -datarep] [arg DATAREP]]
Specifies the data representation on the target. [arg DATAREP]
must be either [const network] (default) or [const native].

[opt_def [cmd -delegate] [arg BOOL]]
If specified as [const true], the server can use the context to
other servers as the client. Requires [cmd -mutualauth] to also
be specified as [const true].

[opt_def [cmd -extendederror] [arg BOOL]]
When [const true], the remote end is notified of errors.

[opt_def [cmd -integrity] [arg BOOL]]
If specified as [const true], messages are to be signed.

[opt_def [cmd -mutualauth] [arg BOOL]]
If specified as [const true], both the client and server are
to be authenticated.

[opt_def [cmd -replaydetect] [arg BOOL]]
If specified as [const true], detection of replayed messages is desired.

[opt_def [cmd -sequencedetect] [arg BOOL]]
If specified as [const true], detection of out-of-sequence messages is desired.

[opt_def [cmd -stream] [arg BOOL]]
If specified as [const true], indicates a stream oriented connection.

[list_end]

[nl]
When a security context is no longer required, it should be released
by calling
[uri #sspi_delete_context [cmd sspi_delete_context]].

[call [cmd sspi_sign] [arg CONTEXT] [arg DATA] [opt [arg options]]]
Generates a signature for [arg DATA] based on the supplied security context.
Returns a list containing the generated signature and [arg DATA].

[call [cmd sspi_schannel_credentials] [opt [arg options]]]
Returns credentials that can be passed to 
the [uri #sspi_acquire_credentials [cmd sspi_acquire_credentials]]
command for SSL/SChannel providers.
The credentials are specified through the following options:
[list_begin opt]
[opt_def [cmd -certificates] [arg CERTLIST]]
[arg CERTLIST] is a list of certificate context handles with private
keys that are used to authenticate the application. Each handle
corresponds to a key exchange method supported by the application.
On the client end, this need not be specified in which case
the provider will find an appropriate
certificate if needed.
[opt_def [cmd -cipherstrength] [arg CIPHERSTRENGTH]]
Specifies the strength of the block ciphers to be used in connections
using the returned credentials. [arg CIPHERSTRENGTH] is list of
one or two elements. The first element is the minimum number of 
bits required in the negotiated encryption key. The second element
is the maximum number of bits in the key and defaults to the minimum
number of bits if the list contains only one element. A value of [const 0]
indicates a system-specific default to be used. A value of [const -1]
indicates a null cipher (no encryption but with message authentication).
This should be used only for debugging purposes.
[opt_def [cmd -protocols] [arg PROTOCOLLIST]]
Specifies the protocols that are acceptable for a connection using
the returned credentials. [arg PROTOCOLLIST] is a list of one or more
of the following: [const ssl2], [const ssl3], [const tls1], [const tls1.1] 
and [const tls1.2].
If unspecified, or if [arg PROTOCOLLIST] is an empty list, 
defaults to the list of protocols configured in the system registry.
[opt_def [cmd -rootstore] [arg HSTORE]]
Specifies a handle to an additional certificate root store that contains
root certificates to authenticate incoming client connections. This
is only used by server applications which need to authenticate clients.
[opt_def [cmd -sessionlifespan] [arg MILLISECS]]
Specifies the number of milliseconds that a Schannel session should be cached.
New connections after this time will require a new session. A value
of [const 0] (default) indicates the system-specific default is to be used.
[list_end]

[call [cmd sspi_shutdown_context] [arg CONTEXT]]
Begins the process of shutting down a context. This command is needed,
and should be called, only for contexts based on the Schannel based
providers. The return value from the command is a pair, the first element
of which is the [const continue], or [const done]. In the former case,
the caller should call [uri #sspi_step [cmd sspi_step]] to continue the 
process of shutting down. In the latter case, the caller can
release the context by calling 
[uri #sspi_delete_context [cmd sspi_delete_context]]. In both cases,
the second element contains binary data to be sent to the remote end 
to complete the shutdown.

[call [cmd sspi_step] [arg CONTEXT] [opt [arg RESPONSE]]]
Depending on the security provider in use, building a security context
may require negotiation with multiple message exchanges between
the client and server. This command
indicates to the caller whether the negotiation is complete or additional
exchange is required. See [sectref "SSPI security context establishment"]
for an overview of this process.

[nl]
[arg CONTEXT] is a handle to the security context being built.
This is the return value from
[uri #sspi_client_context [cmd sspi_client_context]] or
[uri #sspi_server_context [cmd sspi_server_context]].

[nl]
The command returns a list containing two or three elements. The first element
is a status which may be one of the following values:
[list_begin opt]
[opt_def [const done]]
Indicates that the security context negotiation is completed.
The application can use it for cryptographic operations such as signing
or encryption.
[opt_def [const continue]]
The security context negotiation is in progress. Additional steps are
required in the negotiation process and [cmd sspi_step] must be
called again with additional data received from the remote end.
[opt_def [const disconnected]]
The negotiation is terminated and cannot be used for cryptographic
operations. Caller should delete the context using
[uri #sspi_delete_context [cmd sspi_delete_context]].
[list_end]
If the second element of the returned
list is not an empty string, it contains data that must be sent to the
remote end. This is true for [emph "all three cases"] above.
[nl]
Finally, the third element of the returned list, if present, contains leftover
application data after negotiation is complete (indicated by a status of [const done]).
If not empty,
it must be passed to the decryption commands. This occurs for
stream oriented contexts only (like SSL/TLS).

[nl]
The command will raise a Tcl exception if the security context negotiation
fails for any reason, including authentication failures.

[call [cmd sspi_verify_signature] [arg CONTEXT] [arg SIGNATURE] [arg DATA] [opt [arg options]]]
Verifies that the signature [arg SIGNATURE] for the supplied data [arg DATA]
is valid. Generates a Tcl error if the signature is not valid else
returns an integer mask that indicates the level of protection (provider
dependent).

[call [cmd sspi_winnt_identity_credentials] [arg USER] [arg DOMAIN] [arg PASSWORD]]
Returns the credentials based on the specified arguments in a format that
can be passed to the [uri #sspi_acquire_credentials [cmd sspi_acquire_credentials]]
command when NTLM, Kerberos or Negotiate providers are in use.
[arg PASSWORD] should be in the form described in
[uri base.html#passwordprotection "Password protection"].


[list_end]

[keywords authentication "message digest" encryption decryption SSPI schannel Negotiate NTLM Kerberos]

[manpage_end]
