[comment {-*- tcl -*- doctools manpage}]
[manpage_begin "Certificates" n ""]
[copyright "2007-2016 Ashok P. Nadkarni"]
[moddesc "Certificate API"]
[titledesc "Commands related to certificate and PKI operations"]
[require twapi_crypto]
[description]
[para]

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

[para]
This package provides procedures for managing and operating on
digital certificates.

[section "Overview"]

This page describes the commands related to the Win32 CryptoAPI which
deal with X.509 certificates and ancillary services.

[para]
For documentation on other cryptographic operations, see
the [uri crypto.html CryptoAPI] and [uri sspi.html SSPI] pages.

[para]
This documentation expects the reader is familiar with digital certificates.
Otherwise the reader may wish to
refer to the
[uri http://msdn.microsoft.com/en-us/library/windows/desktop/aa380255(v=vs.85).aspx "Windows SDK CryptoAPI documentation"] for detailed guides
and reference documentation.

[section "Certificate stores"]
The CryptoAPI interface provides functions for handling and storage of
X.509 digital certificates.
A [emph "certificate store"] is a container for certificates.
The container may be a physical store, for example on disk,
or a logical store which is a collection of physical stores presented
to the application as a single store.
Certificate stores may also be created as in-memory temporary stores 
which are not persisted.
[para]
Certain certificate stores, called [emph "system stores"]
are predefined by Windows. These include the stores [const MY],
[const ROOT], [const Trust] and [const CA]. Most applications should
store certificates in either the [const MY] store, or in their
own custom store.
[para]
Note that the system stores are relative to a [emph "system store location"]
which must be specified when opening the store.
To enumerate the locations of the system stores, use
[uri #cert_system_store_locations [cmd cert_system_store_locations]].
Optionally, the following predefined values may be used to specify
a system store location:

[list_begin opt]
[opt_def [const user]] Certificates associated with the current user account.
[opt_def [const users]] Certificates shared among all user accounts on the system.
[opt_def [const service]] Certificates associated with the current service account.
[opt_def [const services]] Certificates shared among all services on the system.
[opt_def [const localmachine]] Certificates associated with the system.
[opt_def [const localmachineenterprise]] Certificates downloaded from the
global enterprise directory.
[opt_def [const localmachinegrouppolicy]] Certificates associated with the group policy for the system.
[opt_def [const usergrouppolicy]]  Certificates associated with the group policy for the current user.
[list_end]

To enumerate system stores at a location, use the
[uri #cert_system_stores [cmd cert_system_stores]].

[para]
Most certificate store operations require the store to be first opened
or created. Persistent stores are opened or created
using the one of the commands
[uri #cert_system_store_open [cmd cert_system_store_open]],
[uri #cert_physical_store_open [cmd cert_physical_store_open]] or
[uri #cert_file_store_open [cmd cert_file_store_open]]
as appropriate. Non-persistent stores are created using
[uri #cert_temporary_store [cmd cert_temporary_store]] which includes
various options for populating the store, for example with the contents of
PFX/PKCS #12 or PKCS #7 packets.
[para]
The handle returned from these commands must be passed to any
commands that operate on stores and released by calling
[uri #cert_store_release [cmd cert_store_release]] when no longer required.
[para]
The returned handle from these commands refers to a cached copy of the store.
Any changes made via this handle are made to the cached copy and
must be explicitly saved if they need to persist. This can be done
either via the [cmd -commitenable] option when the store is opened, or
by calling [uri #cert_store_commit [cmd cert_store_commit]].

[para]
Commands
[uri #cert_store_export_pfx [cmd cert_store_export_pfx]],
[uri #cert_store_export_pkcs12 [cmd cert_store_export_pkcs12]],
[uri #cert_store_export_pkcs7 [cmd cert_store_export_pkcs7]],
[uri #cert_store_export_pem [cmd cert_store_export_pem]],
and
[uri #cert_store_serialize [cmd cert_store_serialize]] can be used
to export certificate stores in various formats. 

[para]
Existing certificate stores can be deleted using the commands
[uri #cert_system_store_delete [cmd cert_system_store_delete]],
[uri #cert_physical_store_delete [cmd cert_physical_store_delete]] and
[uri #cert_file_store_delete [cmd cert_file_store_delete]].
A in-memory certificate store is deleted when its handle is closed.

[section "Certificate properties"]
When a certificate is placed
in a store, it is associated with additional properties that are not
part of the certificate itself, for example a private key associated
with the certificate. These properties can be enumerated
with [uri #cert_enum_properties [cmd cert_enum_properties]] and
manipulated with the
[uri #cert_property [cmd cert_property]],
[uri #cert_property_set [cmd cert_property_set]] and
[uri #cert_property_delete [cmd cert_property_delete]] commands.

[section "Certificate contexts"]

Operating on a certificate requires a [emph "certificate context"]
which encapsulates all information about the certificate.
Most often, the certificate of interest is an existing certificate
that is located in a certificate store. The commands for 
finding certificates in a store return a handle to a suitable
certificate context. Similarly, commands that create new certificates
or add certificates to a store return handles to certificate contexts
as well.

[para]
When no longer needed, certificate contexts must be freed by calling
[uri #cert_release [cmd cert_release]].

[section "Getting certificate contents"]

The [uri #cert_info [cmd cert_info]] command returns the fields
in a certificate context. The [uri #cert_extension [cmd cert_extension]]
command retrieves specific extensions. 
Two extensions, Intended Key Usage
and Enhanced Key Usage,
can be also be retrieved with
the [uri #cert_key_usage [cmd cert_key_usage]]
and [uri #cert_enhkey_usage [cmd cert_enhkey_usage]]
command. These look up certificate context properties in addition
to multiple related extensions in the certificate itself.

[para]
The encoded certificate associated with a certificate context can
be retrieved with the [uri #cert_export [cmd cert_export]] command.
This can be written to a file or otherwise distributed.
[example_begin]
set fd [lb]open MyCert.cer w[rb]
chan configure $fd -translation binary
puts -nonewline $fd [lb]cert_export $hcert[rb]
close $fd
[example_end]

[para]
The [uri #cert_locate_private_key [cmd cert_locate_private_key]] command
locates the private key corresponding to the public key in a certificate.

[section "Finding a certificate in a store"]
An existing certificate in a store can be retrieved in one of two ways:
[list_begin bullet]
[bullet] Enumerate each certificate in the store using
[uri #cert_store_enum_contents [cmd cert_store_enum_contents]] and
looking for a match using
[uri #cert_subject_name [cmd cert_subject_name]] or
[uri #cert_property [cmd cert_property]].
[bullet] Searching for a match on the subject name using
[uri #cert_store_find_certificate [cmd cert_store_find_certificate]].
[list_end]
Both these commands return a handle to a certificate context that
can be used for further operations on the certificate.

[section "Creating a new certificate"]
New certificates can be created
by commands such as 
[uri #cert_create_self_signed [cmd cert_create_self_signed]],
[uri #cert_create_signed_from_crypt_context [cmd cert_create_signed_from_crypt_context]] and
[uri #cert_create_certificate [cmd cert_create]].
These return handles to certificate contexts that are not associated with 
any store. The certificates must be explicitly placed in a certificate store
if desired.
[para]
Creating a new certificate involves several steps. As always, first
a cryptographic context is needed that defines the algorithms,
keys etc. that will be used to create the certificate.
[example {set crypt [crypt_acquire -keycontainer twapi_test_container -csp {Microsoft Strong Cryptographic Provider} -csptype prov_rsa_full -create 1]}]
This assumes a key container called twapi_test_container does not exist.
All the options specified above happen to be the defaults if unspecified.
[para]
The key container is created without any keys so we need to generate
public/private key pairs. As we will use the certificate for both
signing only, we specify [const signature] for the second parameter.
[example_begin]
crypt_key_free [lb]crypt_key_generate $crypt signature -exportable 1[rb]
[example_end]
Note we immediately release the key handles as they are not needed. This
does not destroy the underlying keys. We have marked the keys as exportable
because we want to later save them to a file for pedagogic purposes.
In a real application, signature keys should not and need be exportable.
[para]
Next, we create a self signed certificate from the cryptographic context
we created. This will use the keys we just added.
[example {set cert [cert_create_self_signed_from_crypt_context "CN=TwapiTestCA" $crypt]}]

We now have a certificate context for a new self signed certificate.
In most cases, we will want to either store it in a certificate store
for future use or export it to a file. This is illustrated in 
succeeding sections of this document.
[para]
The cryptographic context is not needed any more and can be released.
[example {crypt_free $crypt}]

[para]
Certificates that are not self-signed are created through
[uri #cert_create [cmd cert_create]]. The private key for the signing
certificate must be accessible to the application. The data for
the new certificate, such as the subject name, the certificate public
key, extensions etc. may be provided by the application itself but
more often come from a
[emph "certificate signing request"] which is generated elsewhere,
possibly even on a different system. The command
[uri #cert_request_parse [cmd cert_request_parse]] can be used to
parse such a request and the extracted fields passed to
[uri #cert_create [cmd cert_create]]. The request itself can be
created by [uri #cert_request_create [cmd cert_request_create]].
[para]
On the requester's side, assuming the key container for the requestor
has been already created as in the example above,
[example_begin]
set crypt [lb]crypt_acquire -keycontainer twapi_requestor_container -csp {Microsoft Strong Cryptographic Provider} -csptype prov_rsa_full[rb]
set req [lb]cert_request_create "CN=My Subject Name" $crypt keyexchange -keyusage {key_agreement key_encipherment} -enhkeyusage client_auth[rb]
crypt_free $crypt
[example_end]
The above will create a binary which can be sent to the remote signing
authority where the certificate request contents can be retrieved:
[example {set parsed_req [cert_request_parse $req]}]
After verifying the validity of the request
([emph "how this is done is entirely up to the application"]),
a certificate for the requestor can be created:
[example_begin]
# Assume cissuer is certificate context of signing certificate
set subject [lb]dict get $parsed_req subject[rb]
set pubkey [lb]dict get $parsed_req pubkey[rb]
set opts {}
foreach optname {-basicconstraints -keyusage -enhkeyusage} {
    if {[lb]dict exists $parsed_req extensions $optname[rb]} {
        lappend opts $optname [lb]dict get $parsed_req extensions $optname[rb]
    }
}
set reqcert [lb]cert_create $subject $pubkey $cissuer {*}$opts[rb]
[example_end]
The encoded new certificate returned can be sent back to the requesting
client.

[section "Adding and deleting certificates from a store"]
Certificates can be added and deleted from certificate stores with
the commands
[uri #cert_store_add_certificate [cmd cert_store_add_certificate]]
and [uri #cert_store_delete_certificate [cmd cert_store_delete_certificate]]
respectively. These commands take a certificate context. A certificate
that is in encoded form can be added to a store with
[uri #cert_store_add_encoded_certificate [cmd cert_store_add_encoded_certificate]].
[para]
Note that adding a certificate to a store creates a
[emph copy] of the certificate. The original certificate (context) is
unmodified. 

[para]
The sample code below adds the certificate we created in the previous
section to a temporary in-memory store. First we create the memory store.
[example {set store [cert_temporary_open]}]
Then we add the certificate to it.
[example {set mcert [cert_store_add_certificate $store $cert]}]
This creates a copy of the certificate we created earlier. Since we
no longer need the original, we need to free it.
[example {cert_release $cert}]
There is now one crucial additional step. The association between
a certificate and its private key is maintained by the store and is not
part of the certificate. We therefore have to explicitly make the
association between the CSP key container and the new certificate context
for the temporary store.

[example {cert_set_key_prov $mcert twapi_test_container signature -csp {Microsoft Strong Cryptographic Provider} -csptype prov_rsa_full}]
Notice we have specified exactly the key container we had created earlier.
[para]
The certificate is now stored in the temporary store and will be available
as long as the volatile temporary store is not closed. As a final step
we will export the certificate and the private keys to a file. This step
is only necessary if we want to move the certificate elsewhere. 
(Note if we only wanted to export the certificate without private keys, we
 would follow the procedure in [sectref "Getting certificate contents"].

[example_begin]
set fd [lb]open MyCert.pfx w[rb]
chan configure $fd -translation binary
puts -nonewline $fd [lb]cert_store_export_pfx $store [lb]password[rb] -exportprivate[rb]
close $fd
[example_end]
Note that because we are exporting private keys, a password is required
to protect the exported file.
[para]
Finally, assuming we have no need to hold on to the certificate, we can
free up the resources.
[example_begin]
cert_release $mcert
cert_store_release $store
[example_end]

[section "Certificate validation"]

There are several aspects to validating a certificate. At the very
least, the following must be checked:
[list_begin bullet]
[bullet] the certificate must have a complete chain to
a trusted root certificate authority,
[bullet] the current time must lie in the certificate validity period,
[bullet] none of the certificates in the chain have been revoked,
[bullet] the intended use of the certificate matches that in the certificate
[bullet] the identity specified in the certificate is what is expected
[list_end]

The command
[uri #cert_verify [cmd cert_verify]] verifies certificates as above.
In addition, the commands
[uri #cert_chain_build [cmd cert_chain_build]],
[uri #cert_chain_simple_chain [cmd cert_chain_simple_chain]],
[uri #cert_chain_trust_errors [cmd cert_chain_trust_errors]],
[uri #cert_chain_trust_info [cmd cert_chain_trust_info]] provide
more granular access to the certificate chain used to verify the
certificate.

[section "X.509 alternative names"]
The X.509 certificate extensions allow for a list of alternative names to
be specified for both the certificate subject and issuer. When
passed to commands, this list is formatted as a list of alternating
name format and name value elements. The allowed name formats and
corresponding values are specified in the following table:

[list_begin opt]
[opt_def [const other]]
The value is a pair of elements, the first being an OID and
the second a binary.
[opt_def [const email]]
The value is a RFC 822 email address string.
[opt_def [const dns]]
The value is a DNS name string.
[opt_def [const directory]]
The value is directory name in binary format.
[opt_def [const url]]
The value is a URL string.
[opt_def [const ip]]
The value is a binary octet string containing an IP address.
[opt_def [const registered]]
The value is a registered OID in string format.
[list_end]

[section Commands]

[list_begin definitions]

[call [cmd cert_blob_to_name] [arg ENCODEDBLOB] [opt [arg options]]]
Converts the encoded X.509 ASN encoded name in [arg ENCODEDBLOB]
to a string. The following options control how the returned name
is formatted.
[list_begin opt]
[opt_def [cmd -format] [arg FORMAT]] Specifies how the output
is to be formatted. [arg FORMAT] must be one of [const x500] (default),
[const oid] or [const simple].
[opt_def [cmd -noplus] [arg BOOLEAN]] If [const true], the plus sign
in names is replaced with a single space. Default is [const false].
[opt_def [cmd -noquote] [arg BOOLEAN]] If [const true], quoting of
special characters in RDN names is disabled. Default is [const false].
[opt_def [cmd -reverse] [arg BOOLEAN]] If [const true], order of
RDN components is reversed. Default is [const false].
[opt_def [cmd -separator] [arg SEPARATOR]] Specifies the separator
to use between RDN components.
[arg SEPARATOR] must be one of [const comma] (default), [const semicolon]
or [const newline].
[list_end]

See [uri #cert_name_to_blob [cmd cert_name_to_blob]] for the reverse
operation.

[call [cmd cert_chain_build] [arg HCERT] [opt [arg options]]]
Builds a certificate chain for the specified certificate and returns
a handle to it. The returned handle must be released with
[uri #cert_chain_release [cmd cert_chain_release]].
[nl]
The following options may be specified with the command.

[list_begin opt]
[opt_def [cmd -cacheendcert] [arg BOOLEAN]]
If [arg BOOLEAN] is [const true], the end (leaf) certificate is cached.
Default is [const false].

[opt_def [cmd -disableauthrootautoupdate] [arg BOOLEAN]]
If [arg BOOLEAN] is [const true], auto-update of third party roots
from the Windows update server is disabled.
Default is [const false].

[opt_def [cmd -engine] [arg ENGINE]]
Specifies the chain engine to be used for verification. [arg ENGINE]
must be [const user] (default) or [const machine]. The engine indicates
the namespace and cache to be used for building the verification chain.

[opt_def [cmd -hstore] [arg HSTORE]]
Allows specification of another certificate store to be searched for
supporting certificates. [arg HSTORE] is a handle to a certificate
store as returned by commands like [cmd cert_system_store_open].

[opt_def [cmd -revocationcheck] [arg REVOCATIONSPEC]]
Specifies which certificates in the chain are checked for revocation.
[arg REVOCATIONSPEC] must be one of [const all] (default) indicating
all certificates are to be checked, [const leaf] indicating only
the leaf certificate is to be checked, [const none] which disables
revocation checks, and [const excluderoot] which indicates all
certificates other than the root are to be checked.

[opt_def [cmd -revocationcheckcacheonly] [arg BOOLEAN]]
If [arg BOOLEAN] is [const true], only cached revocation lists are
checked when verifying revocation. Default is [const false].

[opt_def [cmd -urlretrievalcacheonly] [arg BOOLEAN]]
If [arg BOOLEAN] is [const true], only cached URLs are used in building
the certificate chain without searching the network.
Default is [const false].

[opt_def [cmd -usageall] [arg USAGELIST]]
Specifies that the certificate enhanced key usage field must include
[emph all] the values for [arg USAGELIST]. [arg USAGELIST]
is a list containing OID's or the following values: 
[const server_auth], [const client_auth], [const code_signing], 
[const email_protection],
[const ipsec_end_system], [const ipsec_tunnel], [const ipsec_user], 
[const timestamp_signing] or [const ipsec_ike_intermediate].

[opt_def [cmd -usageany] [arg USAGELIST]]
Specifies that the certificate enhanced key usage field must include
[emph any] of the values for [arg USAGELIST]. [arg USAGELIST]
is as described for the [cmd -usageall] option above.

[list_end]

[call [cmd cert_chain_trust_errors] [arg HCHAIN]]
Returns a list of verification failure codes associated with the
specified certificate chain. An empty list indicates no errors were
found in any of the chain components.
[nl]
The failure codes include
[const time],
[const revoked],
[const signature],
[const wrongusage],
[const untrustedroot],
[const revocationunknown],
[const trustcycle],
[const extension],
[const policy],
[const basiconstraints],
[const nameconstraints],
[const unsupportednameconstraint],
[const undefinednameconstraint],
[const unpermittednameconstraint],
[const excludednameconstraint],
[const revocationoffline],
[const noissuancechainpolicy],
[const distrust],
[const criticalextension],
[const weaksignature],
[const partialchain],
[const ctltime],
[const ctlsignature],
[const ctlusage].
[nl]
The returned list may include values not listed above. These should
be also be treated as verification failures.
[nl]
Note that this command is not sufficient to check for certificate
verification for all purposes. For example, it does not check if
a server name on a TLS connection matches the certificate. Applications
should therefore generally use the higher level
[uri #cert_verify [cmd cert_verify]] for certificate verification.

[call [cmd cert_chain_trust_info] [arg HCHAIN]]
Returns a list of informational codes associated with the
specified certificate chain. Note these are not verification errors.
The returned list may include zero or more of the following codes:
[const hasexactmatchissuer],
[const haskeymatchissuer],
[const hasnamematchissuer],
[const isselfsigned],
[const haspreferredissuer],
[const hasissuancechainpolicy],
[const hasvalidnameconstraints],
[const ispeertrusted],
[const hascrlvalidityextended],
[const isfromexclusivetruststore],
[const iscomplexchain].
Codes other than those listed above may also be present.

[call [cmd cert_chain_release] [arg HCHAIN]]
Releases the handle to a certificate chain returned by
[uri #cert_chain_build [cmd cert_chain_build]].

[call [cmd cert_chain_simple_chain] [arg HCHAIN] [arg INDEX]]
Returns a dictionary containing information about
the simple chain at position [arg INDEX] in the list of simple chains
within a certificate chain.
*NOTE: the returned value may include handles to certificate contexts.
These must be freed. See the description of the [const hcert] element
later.*
[nl]
A certificate chain may consists of a list of one or more
*simple chains*. Each simple chain is a list of certificates ending
in a self signed certificate. If the self signed certificate is a
trusted root certificate, the chain is complete. Otherwise, the
simple chain is linked (if possible) to another simple chain
through a certificate trust list (CTL) which connects the self signed
certificate to the next simple chain in the list.
In most cases, the certificate chain contains a single simple chain
the last element of which is a trusted root certificate.

[nl]
The number of simple chains in a certificate chain is returned by
[uri #cert_chain_simple_chain_count [cmd cert_chain_simple_chain_count]].
The command will raise an exception if [arg INDEX] is not in this range.
[nl]
The returned dictionary has the following elements.
[list_begin opt]
[opt_def [const chain]]
A list whose elements correspond to each certificate in the simple chain.
This is detailed below.
[opt_def [const status]]
Contains [const ok] if no verification errors are present in this
simple chain, else [const fail].
[opt_def [const trust_errors]] A list containing the verification errors
for the simple chain. The elements of the list are from
the same set of values described in
[uri #cert_chain_trust_errors [cmd cert_chain_trust_errors]] which
covers the entire certificate chain.
[opt_def [const trust_info]] A list containing informational codes
for the simple chain. The elements of the list are from
the same set of values described in
[uri #cert_chain_trust_info [cmd cert_chain_trust_info]] which
covers the entire certificate chain.
[list_end]

The [const chain] element of the returned dictionary is a list of
dictionaries corresponding to each certificate in the simple chain.
This dictionary has the following elements.
[list_begin opt]
[opt_def [const application_usage]]
A list of enhanced key usage identifiers. This dictionary element
may not be present if the corresponding certificate fields were not present.
[opt_def [const issuance_usage]]
A list of issuance policy identifiers. This dictionary element
may not be present if the corresponding certificate fields were not present.
[opt_def [const hcert]]
Handle to the certificate context.
*This must be freed by calling [uri #cert_release [cmd cert_release]].*
[opt_def [const status]]
Contains [const ok] if no verification errors are present in this
certificate, else [const fail].
[opt_def [const trust_errors]] A list containing the verification errors
for the certificate. The elements of the list are from
the same set of values described in
[uri #cert_chain_trust_errors [cmd cert_chain_trust_errors]] which
covers the entire certificate chain.
[opt_def [const trust_info]] A list containing informational codes
for this certificate. The elements of the list are from
the same set of values described in
[uri #cert_chain_trust_info [cmd cert_chain_trust_info]] which
covers the entire certificate chain.
[list_end]
Any additional keys in the dictionary should be ignored.

[call [cmd cert_chain_simple_chain] [arg HCHAIN]]
Returns the number of simple chains in the passed certificate chain.

[call [cmd cert_create] [arg SUBJECT] [arg PUBKEY] [arg ISSUERCERT] [opt [arg options]]]
Creates a certificate and returns it in ASN.1 DER-encoded
or PEM base-64 encoded format ([emph not] as a certificate context).
[arg SUBJECT] is the name of the subject in X.500 format.
[arg PUBKEY] is the public key for the certificate subject.
[arg ISSUERCERT] is the certificate context that will be used to
sign the created certificate. The private key associated with this
certificate must be accessible to the current process context.
The subject name, and alternate name extension if present, from [arg ISSUERCERT]
will be stored as the issuer name and issuer alternate name extension
in the generated certificate.
[nl]
The following options can be specified for the command:
[list_begin opt]
[opt_def [cmd -altnames] [arg ALTNAMES]]
Specifies X.509 Alternative Name values to include in the certificate.
[arg ALTNAMES] is a pair of one or two elements.
The first is a list of pairs containing the name type and name value
as described in [sectref "X.509 alternative names"].
The second element, which is optional and defaults to [const false],
is a boolean indicating whether the corresponding certificate extension
should be marked critical or not.
[opt_def [cmd -basicconstraints] [arg BASICCONSTRAINTS]]
Specifies a basic constraints extension to be included in the certificate.
[arg BASICCONSTRAINTS] is a pair of one or two elements.
The first is a triplet consisting of a boolean which should be [const true]
if the certificate is to be used for a certificate authority, a boolean
that indicates whether the path length value is to be enforced, and
a non-negative integer which is the path length value itself. These last
are only relevant if the first is [const true].
The second element of [arg BASICCONSTRAINTS],
which is optional and defaults to [const true],
is a boolean indicating whether the corresponding certificate extension
should be marked critical or not.
This element cannot be specified if the [cmd -purpose] option is specified
and contains the value [const "ca"].
[opt_def [cmd -capathlen] [arg CAPATHLENGTH]]
Specifies the limit on the certificate chain path length during verification.
Ignored unless the [cmd -purpose] option includes [const ca].
[opt_def [cmd -end] [arg ENDTIME]]
Specifies the end of the certificate validity period. [arg ENDTIME] must
be of the form [arg "Year-Month-Day Hour:Minutes:Seconds"].
Defaults to one year beyond the start time.
[opt_def [cmd -enhkeyusage] [arg ENHKEYUSAGE]]
Specifies values to use for the X.509 enhanced key usage extension.
[arg ENHKEYUSAGE] is a pair of one or two elements, the first of which
is a list containing one or more values from 
[const client_auth], [const code_signing], [const email_protection],
[const ipsec_endsystem], [const ipsec_tunnel],
[const ipsec_user], [const server_auth], [const ocsp_signing],
[const timestamp_signing] or a valid [uri #asn1objectidentifiers OID].
The second element, which is optional and defaults to [const false],
is a boolean indicating whether the corresponding certificate extension
should be marked critical or not.
[opt_def [cmd -encoding] [arg ENCODING]]
Specifies the encoding in which the encoded certificate is returned.
[arg ENCODING] may be [const der] or [const pem] (default)
for DER- and PEM-encoding respectively.
[opt_def [cmd -keyusage] [arg KEYUSAGE]]
Specifies values to use for the X.509 key usage extension.
[arg KEYUSAGE] is a pair of one or two elements, the first of which
is a list containing one or more values from 
[const crl_sign], [const data_encipherment], [const decipher_only]
[const digital_signature], [const encipher_only], [const key_agreement],
[const key_cert_sign], [const key_encipherment] and [const non_repudiation].
The second element, which is optional and defaults to [const false],
is a boolean indicating whether the corresponding certificate extension
should be marked critical or not.
[opt_def [cmd -purpose] [arg PURPOSELIST]]
Specifies the purposes for which the certificate is to be used. This
is a more convenient method of specifying common
extensions. Use of this adds appropriate extensions but does not
preclude caller from specifying other extension-based options.
[arg PURPOSELIST] must be a list containing zero or more items
from the following:
[list_begin opt]
[opt_def [const ca]] Indicates that the certificate may be used
to sign other certificates as a certificate authority. Sets the
[const basic_constraints] extension and the [const key_cert_sign]
and [const crl_sign] bits of the keyusage extension. The
[cmd -basicconstraints] option can be specified in this case.
[opt_def [const client]] Indicates the certificate will
be used for a SSL/TLS client. Sets
[const digital_signature], [const key_encipherment] and [const key_agreement]
in the key usage extension and [const oid_pkix_kp_client_auth]
in the enhanced key extension.
[opt_def [const server]] Indicates the certificate will
be used for a SSL/TLS server. Sets
[const digital_signature], [const key_encipherment] and [const key_agreement]
in the key usage extension and [const oid_pkix_kp_server_auth]
in the enhanced key extension.
[list_end]
[opt_def [cmd -signaturealgorithm] [arg SIGLAGORITHM]]
Specifies the signature algorithm to use for signing the certificate.
[opt_def [cmd -start] [arg STARTTIME]]
Specifies the start of the certificate validity period. 
[arg STARTTIME] must be
of the form [arg "Year-Month-Day Hour:Minutes:Seconds"].
Defaults to the current time.
[list_end]

[call [cmd cert_create_self_signed] [arg SUBJECT] [arg KEYCONTAINER] [arg KEYSPEC] [opt [arg options]]]
Creates a new certificate context for a self-signed certificate
and returns a handle to it.
[arg KEYCONTAINER] specifies the name of the key container containing
the private key to use for signing. [arg KEYSPEC], which must be either
[const keyexchange] or [const signature], specifies the key within that
container.
[nl]
[arg SUBJECT] is the name of the subject (and issuer) in X.500 format.
[nl]
The following options may be specified:
[list_begin opt]
[opt_def [cmd -altnames] [arg ALTNAMES]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -capathlen] [arg CAPATHLENGTH]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -csp] [arg CSP]] Specifies the name of the CSP to be used.
If unspecified, the default Microsoft CSP for the system is used.
[opt_def [cmd -csptype] [arg CSPTYPE]] Indicates the type of
CSP. Defaults to [const prov_rsa_full]. 
See [sectref "Cryptographic Service Providers"] for all possible types.
[opt_def [cmd -end] [arg ENDTIME]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -enhkeyusage] [arg ENHKEYUSAGE]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -keysettype] [arg KEYSETTYPE]]
[arg KEYSETTYPE] type must be [const user] (default) or [const machine]
depending on whether the key container is user-specific or not.
[opt_def [cmd -keyusage] [arg KEYUSAGE]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -purpose] [arg PURPOSELIST]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -silent] [arg BOOLEAN]] Normally, the CSP may prompt the user
for any information that may be required to retrieve the keys. If this
option is specified as [const true], the user is never prompted. Instead
the command will raise an error if a user prompt would have been required.
[opt_def [cmd -signaturealgorithm] [arg SIGLAGORITHM]]
Specifies the signature algorithm to use for signing the certificate.
[arg SIGLAGORITHM] is the OID (see [sectref "ASN.1 Object Identifiers"])
corresponding to a signature algorithm. Defaults to the SHA1RSA algorithm
if unspecified.
[opt_def [cmd -start] [arg STARTTIME]]
See [uri #cert_create [cmd cert_create]]
[list_end]

The returned certificate handle must be freed by calling
[uri #cert_release [cmd cert_release]].

Alternatively, the 
[uri #cert_create_self_signed_from_crypt_context [cmd cert_create_self_signed_from_crypt_context]]
may be used instead if a handle to a cryptographic context is already
available.

[call [cmd cert_create_self_signed_from_crypt_context] [arg SUBJECT] [arg HCRYPT] [opt [arg options]]]
Creates a new certificate context for a self-signed certificate
and returns a handle to it. The certificate is signed using the
cryptographic context referenced by [arg HCRYPT]. Alternatively, the 
[uri #cert_create_self_signed [cmd cert_create_self_signed]]
may be used instead to explicitly specify the CSP and key container.
[nl]
[arg SUBJECT] is the name of the subject (and issuer) in X.500 format.
[nl]
The following options may be specified:
[list_begin opt]
[opt_def [cmd -altnames] [arg ALTNAMES]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -capathlen] [arg CAPATHLENGTH]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -end] [arg ENDTIME]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -enhkeyusage] [arg ENHKEYUSAGE]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -keyusage] [arg KEYUSAGE]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -purpose] [arg PURPOSES]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -silent] [arg BOOLEAN]]
See [uri #cert_create_self_signed [cmd cert_create_self_signed]].
[opt_def [cmd -signaturealgorithm] [arg SIGLAGORITHM]]
See [uri #cert_create_self_signed [cmd cert_create_self_signed]].
[opt_def [cmd -start] [arg STARTTIME]]
See [uri #cert_create [cmd cert_create]]
[list_end]

The returned certificate handle must be freed by calling
[uri #cert_release [cmd cert_release]].

[call [cmd cert_duplicate] [arg HCERT]]
Duplicates a certificate context and returns a handle to it. The returned
certificate context handle may be the same as [arg HCERT] with its
reference count increased.
[nl]
The returned certificate context must be freed by calling
[uri #cert_release [cmd cert_release]].

[call [cmd cert_enhkey_usage] [arg HCERT] [opt [arg SOURCE]]]
Returns a list of OID's based on the Enhanced Key Usage (EKU) certificate
extension content and/or the EKU certificate property.
If [arg SOURCE] is not specified or is [const both], the
OID's present in both the extension [emph and] the property
are returned. If [arg SOURCE] is [const extension] or [const property]
only those corresponding values are returned, the other is not
considered. In the case where neither the extension nor the property is
present, the string [const *] is returned indicating the certificate
is considered valid for all uses. If the returned list is empty,
the certificate is considered invalid for any use.

[call [cmd cert_enum_properties] [arg HCERT] [opt [cmd -names]]]
Returns a list of properties defined for the certificate context [arg HCERT].
By default, the returned list contains integer property ids.
If [cmd -names] is specified, the returned list contains the mnenomic
for the property id 
(see [uri #cert_property [cmd cert_property]]) if defined, and
the integer value otherwise.

[call [cmd cert_export] [arg HCERT] [opt "[cmd -encoding] [arg ENCODING]"]]
Returns the certificate content for the specified certificate context.
The [cmd -encoding] option controls the encoding of the returned content.
[arg ENCODING] may be [const der] or [const pem] (default)
for DER- and PEM-encoding respectively.

[call [cmd cert_extension] [arg HCERT] [arg EXTENSION]]
Returns a certificate extension as a two element list.
The first element is a boolean indicating whether the extension
is marked critical. The second element is the value of the extension.
[arg EXTENSION] is the OID for the extension, either in dotted
decimal or mnemonic form.

[call [cmd cert_file_store_open] [arg PATH] [opt [arg options]]]
Opens a certificate store from a file [arg PATH]
and returns a handle to a cached copy of it.
The following options may be specified:

[list_begin opt]

[opt_def [cmd -backupprivilege] [arg BOOLEAN]]
If [const true], specifies that the thread's [const SE_BACKUP_NAME]
and [const SE_RESTORE_NAME] privileges must be used to open the store.
Default is [const false].

[opt_def [cmd -commitenable] [arg BOOLEAN]]
If [const true], any changes made to the store are persisted to [arg PATH]
when the store is closed. Default is [const false]. 

[opt_def [cmd -create] [arg BOOLEAN]]
If [const true], a new store is opened only if it did not exist. An error
is raised if the store already existed.
Default is [const false] so no error is raised in the latter case.

[opt_def [cmd -deferclose] [arg BOOLEAN]]
Normally changes to any certificate contexts made after the associated store
is closed are not persisted. Setting this option to [const true] will
defer the closing of the store until all associated certificate contexts
have been released.
Default is [const false].

[opt_def [cmd -existing] [arg BOOLEAN]]
If [const true], when [arg PATH] does not already exist, it is not created.
An exception is raised instead.
Default is [const false].
[opt_def [cmd -includearchived] [arg BOOLEAN]]
By default, enumeration of certificates in a store will not include any
that are marked as archived. Setting this option to [const true] will
cause those certificates to be included.
Default is [const false].
[opt_def [cmd -maxpermissions] [arg BOOLEAN]]
If [const true], the store is opened with the maximum set of access permissions
possible.
Default is [const false].
[opt_def [cmd -readonly] [arg BOOLEAN]]
If [const true], the underlying file is opened in read-only mode. However,
changes can still be made to the in-memory cache.
Default is [const false].
[list_end]

The certificate store is written to the file in PKCS #7 format if the file
name extension is [const .p7c] or [const .spc], or if the file was empty.
Otherwise the file is written as a serialized certificate store.
[nl]
The store must be closed with [uri #cert_store_release [cmd cert_store_release]]
when no longer needed.

[call [cmd cert_import] [arg ENCODEDCERT] [opt "[cmd -encoding] [arg encoding]"]]
Creates and returns a certificate context from encoded data in
[arg ENCODEDCERT]. 
[arg ENCODING] may be [const der] or [const pem]
depending on whether [arg ENCODEDCERT] uses DER- or PEM-encoding.
If unspecified, the command attempts to determine the encoding itself.
For performance reasons, the encoding should be explicitly specified
when possible.

[call [cmd cert_info] [arg HCERT]]
Returns the following fields from a certificate context as a dictionary.
[list_begin opt]
[opt_def [const -end]] The end of the certificate's validity period
in the format [arg "Year-Month-Day Hour:Minutes:Seconds"]
[opt_def [const -extensions]] A list of extensions in the certificate.
Each element is a triplet containing the OID of the extension,
a boolean indicating whether the extension is marked critical or not,
and the extension value.
[opt_def [const -issuer]] The name of the certificate issuer.
[opt_def [const -issuerid]] A binary containing unique id for
the certificate issuer. This is generally not used and should not
be relied on.
[opt_def [const -publickey]] The public key of the subject. This is
a pair consisting of the algorithm identifier 
(in the same format as [const -signaturealgorithm]) and a binary
containing the public key.
[opt_def [const -serialnumber]] A binary containing the serial number
of the certificate.
[opt_def [const -signaturealgorithm]] A pair consisting of the OID 
for the algorithm used to sign the certificate and a binary containing
any associated parameters.
[opt_def [const -start]] The start of the certificate's validity period
in the format [arg "Year-Month-Day Hour:Minutes:Seconds"].
[opt_def [const -subject]] The name of the certificate subject.
[opt_def [const -subjectid]] A binary containing unique id for
the certificate subject. This is generally not used and should not
be relied on.
[opt_def [const -version]] The X.509 version of the certificate. Note
this is 0-based on V3 certificates will have a value of [const 2].
[list_end]

[call [cmd cert_issuer_name] [arg HCERT] [opt [arg options]]]
Returns an issuer name field from the certificate context [arg HCERT]. 
The field may be from the certificate itself or a certificate property
in the context. The command returns an empty string if the specified name 
field does not exist in the certificate.
[nl]
Refer to [uri #cert_subject_name [cmd cert_subject_name]] for a list
of options.

[call [cmd cert_key_usage] [arg HCERT]]
Returns a list of the Intended Key Usage values in a certificate.
The command looks for both the extensions [const 2.5.29.2] and
[const 2.5.29.15].
In the case where the extension is not
present, the string [const *] is returned indicating the certificate
may be used for any purpose.

[call [cmd cert_locate_private_key] [arg HCERT] [opt [arg options]]]
Searches key containers to locate the private key corresponding to
the public key in the certificate context [arg HCERT]. Returns a
boolean indicating if it was found. In addition, the located key is
associated as a property of the certificate and can be retrieved
as the [const key_prov_info] property using the
[uri #cert_property [cmd cert_property]] command.
[nl]
The following options may be specified:
[list_begin opt]
[opt_def [cmd -keysettype] [const any|user|machine]]
Specifies which key sets are to be searched for the private key.
If [const user] or [const machine], the search is restricted to
the containers for the current user or the machine respectively.
If [const any] (default), both user and machine containers are searched.
[opt_def [cmd -silent] [arg BOOLEAN]] Normally, the CSP may prompt the user
for any information that may be required to access key containers. If this
option is specified as [const true], the user is never prompted. Instead
the command will return [const 0] indicating no key could be found.
[list_end]

[call [cmd cert_name_to_blob] [arg NAME] [opt [arg options]]]
Converts the string [arg NAME] to an X.509 ASN encoded binary.
The following options control the allowed format for [arg NAME].
[list_begin opt]
[opt_def [cmd -format] [arg FORMAT]] Specifies how [arg NAME] is
formatted. [arg FORMAT] must be one of [const x500] (default),
[const oid] or [const simple].
[opt_def [cmd -noplus] [arg BOOLEAN]] If [const true], the plus sign
in [arg NAME] is not treated as a value separator. Default is [const false].
[opt_def [cmd -noquote] [arg BOOLEAN]] If [const true], quoting is
not supported in [arg NAME]. Default is [const false].
[opt_def [cmd -reverse] [arg BOOLEAN]] If [const true], order of
RDN components in [arg NAME] 
is reversed before encoding. Default is [const false].
[opt_def [cmd -separator] [arg SEPARATOR]] If unspecified, 
commans and semicolons are parsed as separators. If specified,
only [arg SEPARATOR] is treated as a separator. 
[arg SEPARATOR] must be one of [const comma] (default), [const semicolon]
or [const newline]. In the case of [const newline], carriage return
and linefeed characters are treated as separators.
[list_end]

See [uri #cert_blob_to_name [cmd cert_blob_to_name]] for the reverse
operation.

[call [cmd cert_physical_store_open] [arg NAME] [arg LOCATION] [opt [arg options]]]
Opens a certificate physical store that is part of a logical system
store and returns a handle to a cached copy.
[arg NAME] is the name of the physical store including the
system store component, e.g. [const Root\\.Default]. [arg LOCATION]
specifies the location of the system store and must be one of
the values listed in [sectref "Certificate stores"].
[nl]
Refer to the documentation of
[uri #cert_system_store_open [cmd cert_system_store_open]] of a description
of [arg options].
[nl]
The store must be closed with [uri #cert_store_release [cmd cert_store_release]]
when no longer needed.

[call [cmd cert_physical_store_delete] [arg NAME] [arg LOCATION]]
Deletes a certificate physical store that is part of a logical system
store. [arg NAME] is the name of the physical store including the
system store component, e.g. [const Root\\.Default]. [arg LOCATION]
specifies the location of the system store and must be one of
the values listed in [sectref "Certificate stores"].

[call [cmd cert_property] [arg HCERT] [arg PROPERTY]]
Returns the value of a 
[uri #certificateproperties "certificate property"] in
the certificate context referenced by [arg HCERT]. Raises
an error if the property does not exist in the certificate context.

[arg PROPERTY] must be one of the following:
[list_begin opt]
[opt_def [cmd access_state]] A non-0 integer if write operations
to the certificate context are persisted and 0 if they are not.
[opt_def [cmd archived]] If this property exists, the certificate is
an archived certificate.
[opt_def [cmd auto_enroll]] The certificate type for which
this certificate has been auto-enrolled.
[opt_def [cmd date_stamp]] The date and time that the certificate was
added to the store.
[opt_def [cmd description]] The description associated with the certificate
for display purposes.
[opt_def [cmd enhkey_usage]] A list of enhanced key usage OID's.
[opt_def [cmd extended_error_info]] Any extended error information
for the certificate context.
[opt_def [cmd friendly_name]] The display name for the certificate.
[opt_def [cmd issuer_public_key_md5_hash]] The MD5 hash of the issuer's public
key used to sign the certificate.
[opt_def [cmd issuer_serial_number_md5_hash]]
The MD5 hash of the issuer name and serial number.
[opt_def [cmd key_context]] A list of two elements containing a handle
to the cryptographic context for the certificate and the key type.
[opt_def [cmd key_identifier]] A binary containing the Subject Key Identifier
value if it exists else the SHA1 hash on the certificate Subject Public Key.
[opt_def [cmd key_prov_handle]] A handle to the associated cryptographic
context.
[opt_def [cmd key_prov_info]] A list containing the following elements:
the name of the key container, the name of the CSP, the CSP type,
attributes, key container parameters and the key type.
[opt_def [cmd key_spec]] Specifies the private key.
[opt_def [cmd md5_hash]] Binary containing the MD5 hash of the certificate.
[opt_def [cmd pvk_file]] File path of the private key file corresponding
to the certificate's public key.
[opt_def [cmd sha1_hash]] Binary containing the SHA1 hash of the certificate.
This can also be retrieved as a hexadecimal string with
[uri #cert_thumbprint [cmd cert_thumbprint]].
[opt_def [cmd signature_hash]] Signature hash.
[opt_def [cmd subject_name_md5_hash]] Binary containing the MD5 hash of the
encoded subject name.
[opt_def [cmd subject_public_key_md5_hash]] Binary containing the MD5 hash of the certificate public key.
[list_end]

[call [cmd cert_property_delete] [arg HCERT] [arg PROPERTY]]
Deletes a [uri #certificateproperties "certificate property"] in
the certificate context referenced by [arg HCERT]. No error is
raised if the property does not exist.
[arg PROPERTY] must be one of the property names
listed in the documentation for [uri #cert_property [cmd cert_property]].

[call [cmd cert_property_set] [arg HCERT] [arg PROPERTY] [arg PROPVAL]]
Sets the value of a [uri #certificateproperties "certificate property"] in
the certificate context referenced by [arg HCERT].
[arg PROPERTY] must be one of 
[const description], [const friendly_name] or [const pvk_file]
(see [uri #cert_property [cmd cert_property]]).

[call [cmd cert_release] [arg HCERT]]
Decreases the reference count for a certificate context and
frees it if the result is 0.

[call [cmd cert_request_create] [arg SUBJECT] [arg HCRYPT] [arg KEYSPEC] [opt [arg options]]]
[arg SUBJECT] is the name of the subject in X.500 format.
Returns an encoded certificate signing request (CSR) that can be sent
to a certificate authority. [arg HCRYPT] and [arg KEYSPEC]
together select the public/private key pair
for which a certificate is to be requested.
[arg HCRYPT] is a handle to a
cryptographic context and
[arg KEYSPEC] must be [const signature] or [const keyexhange] to
select the appropriate key pair in the context.
[nl]
The following options may be specified:
[list_begin opt]
[opt_def [cmd -altnames] [arg ALTNAMES]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -capathlen] [arg CAPATHLENGTH]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -encoding] [arg ENCODING]]
Specifies the encoding of the returned CSR.
[arg ENCODING] may be [const der] or [const pem] (default)
for DER- and PEM-encoding respectively.
[opt_def [cmd -enhkeyusage] [arg ENHKEYUSAGE]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -keyusage] [arg KEYUSAGE]]
See [uri #cert_create [cmd cert_create]]
[opt_def [cmd -purpose] [arg PURPOSES]]
See [uri #cert_create [cmd cert_create]]
[list_end]

[call [cmd cert_request_parse] [arg CSR] [opt "[cmd -encoding] [arg ENCODING]"]]
Parses a certificate signing request [arg CSR] and returns a dictionary with
its contents. 
[arg ENCODING] may be [const der] or [const pem]
depending on whether [arg ENCODEDCERT] uses DER- or PEM-encoding.
If unspecified, the command attempts to determine the encoding itself.
[nl]
The returned dictionary has the following keys:
[list_begin opt]
[opt_def [cmd attributes]] The attribute field in the CSR. This
is a list each element of which is a pair consisting of an OID
and a list of corresponding values.
[opt_def [cmd extensions]] A subset of the [cmd attributes] key,
formatted for easier processing. See the discussion below. This key
may be absent if the attributes do not contain any extensions.
[opt_def [cmd pubkey]] The public key of the requestor. This should
be passed to [uri #cert_create [cmd cert_create]] as the public key
argument.
[opt_def [cmd subject]] The subject name of the requestor. This should
be passed to [uri #cert_create [cmd cert_create]] as the subject
argument.
[opt_def [cmd version]] The CSR format version number.
[list_end]

One of the potential attribute fields in a CSR is
OID [const 1.2.840.113549.1.9.14] through which the requestor
can indicate certain certificate extensions to be included in
the returned certificate. This specific attribute is parsed and
returned as the value of the [cmd extensions] dictionary element above.
This value is itself a dictionary which may contain zero or more of the
keys [cmd -basicconstraints], [cmd -keyusage] and [cmd -enhkeyusage].
The corresponding values have the same format as the corresponding
options to the [uri #cert_create [cmd cert_create]] command.

[call [cmd cert_set_key_prov] [arg HCERT] [arg KEYCONTAINER] [arg KEYSPEC] [opt [arg options]]]
Associates the certificate context [arg HCERT] with the CSP key container
[arg KEYCONTAINER].
[arg KEYSPEC] must be one of
[const keyexchange] (default) or [const signature] and identifies
the key within the container.
The following options may be specified.

[list_begin opt]
[opt_def [cmd -csp] [arg CSP]] Specifies the name of the CSP for
the container.
If unspecified, the default Microsoft CSP for the system is used.
[opt_def [cmd -csptype] [arg CSPTYPE]] Indicates the type of
CSP. Defaults to [const prov_rsa_full]. 
See [sectref "Cryptographic Service Providers"] for all possible types.
[opt_def [cmd -keysettype] [arg KEYSETTYPE]] [arg KEYSETTYPE] must be
[const user] (default) or [const machine].
[opt_def [cmd -silent] [arg BOOLEAN]] Normally, the CSP may prompt the user
for any information that may be required to create the context. If this
option is specified as [const true], the user is never prompted. Instead
the command will raise an error if a user prompt was required.
[list_end]

[call [cmd cert_store_add_certificate] [arg HSTORE] [arg HCERT] [opt "[cmd -disposition] [arg DISPOSITION]"]]
Adds a new certificate to a certificate store. [arg HSTORE] is the handle
to the store and [arg HCERT] is a handle to a certificate context.
The new certificate is a [emph copy] of [arg HCERT]. The command returns
a handle to the new certificate context which must be freed
with [uri #cert_release [cmd cert_release]] when no longer needed. 
Note that the new certificate is not persisted until the store is saved.
[nl]
Any properties associated with [arg HCERT] are also copied to the new
certificate context with the exception of any key associations.
These must be explicitly added to the new context if desired using
[uri #cert_set_key_prov [cmd cert_set_key_prov]].
[nl]
The [cmd -disposition] option controls what happens if a matching
certificate already exists in the store. [arg DISPOSITION] may take one
of the following values:
[list_begin opt]
[opt_def duplicate] Creates the new certificate while keeping the existing
one. This will create duplicates in the store.
[opt_def overwrite] Overwrites the existing certificate with the new one.
[opt_def preserve] (default) If a matching certificate exists, it is preserved
and a error raised. Otherwise, the new certificate is added.
[opt_def update] The new certificate is added if there is no matching
certificate or the matching certificate's validity period start time
is less than that of the new certificate. Otherwise an error is raised.
[list_end]

[call [cmd cert_store_add_encoded_certificate] [arg HSTORE] [arg ENCODEDCERT] [opt [arg options]]]
Adds a new certificate to a certificate store. [arg HSTORE] is the handle
to the store. [arg ENCODEDCERT] is a binary value containing the 
certificate encoded in X.509 ASN.1 format.
The command returns
a handle to the new certificate context which must be freed
with [uri #cert_release [cmd cert_release]] when no longer needed. 
Note that the new certificate is not persisted until the store is saved.
[nl]
Supported options are:
[list_begin opt]
[opt_def [cmd -disposition] [arg DISPOSITION]]
Controls what happens if a matching
certificate already exists in the store. [arg DISPOSITION] may take one
of the following values:
[list_begin opt]
[opt_def duplicate] Creates the new certificate while keeping the existing
one. This will create duplicates in the store.
[opt_def overwrite] Overwrites the existing certificate with the new one.
[opt_def preserve] (default) If a matching certificate exists, it is preserved
and a error raised. Otherwise, the new certificate is added.
[opt_def update] The new certificate is added if there is no matching
certificate or the matching certificate's validity period start time
is less than that of the new certificate. Otherwise an error is raised.
[list_end]
[opt_def [cmd -encoding] [arg ENCODING]]
Specifies the encoding of [arg ENCODEDCERT].
[arg ENCODING] should be [const der] or [const pem]
depending on whether [arg ENCODEDCERT] uses DER- or PEM-encoding. If unspecified
or the empty string, the command will attempt to make the determination itself.
[list_end]

[call [cmd cert_store_commit] [arg HSTORE] [opt "[cmd -force] [arg BOOLEAN]"]]
Commits any changes made to a certificate store. If [cmd -force] is
specified as [const true], the store is written out even if no changes
have been made to the in-memory copy.

[call [cmd cert_delete_from_store] [arg HCERT]]
Deletes the specified certificate context from its containing store.
Also decreases the reference count on the certificate context.

[call [cmd cert_fetch] [arg IPADDR] [arg PORT]]
Returns a certificate context for a remote server certificate by
establishing a TLS connection to it. The connection is closed before
the command returns. The returned handle to the certificate context
must be released by calling [uri #cert_release [cmd cert_release]].

[call [cmd cert_store_enum_contents] [arg HSTORE] [opt [arg HCERT]]]
The command returns a handle to a certificate context for 
the next certificate in the store specified by the handle
[arg HSTORE]. When [arg HCERT] is not specified or is specified as
[const NULL], the enumeration starts from the first certificate in the store.
If [arg HCERT] is specified, it must be a handle to a certificate context
returned by a previous call to the command. The command then returns
the next certificate in the store. The command also frees [arg HCERT]
(even in case of errors) so caller must not access it after the command
returns. If [arg HCERT] needs to be accessed later, use the
[uri #cert_duplicate [cmd cert_duplicate]] command to make a copy first.
[nl]
A certificate context handle returned by the command that is
not passed back in as [arg HCERT] in a subsequent call, must be released
by calling [uri #cert_release [cmd cert_release]].
[nl]
The command returns an
empty string when there are no more certificates in the store.
[nl]
The command 
[uri #cert_store_find_certificate [cmd cert_store_find_certificate]]
offers another means for retrieving certificates from a store.

[call [cmd cert_store_export_pem] [arg HSTORE]]
Returns all certificates in a store in PEM encoded format. This format is
commonly used with the [cmd openssl] program's [cmd -CAfile] option.

[call [cmd cert_store_export_pfx] [arg HSTORE] [arg PASSWORD] [opt [arg options]]]
Returns a binary containing all the certificates in a certificate store
in PFX (PKCS #12) format.
[arg HSTORE] is a handle to the store and [arg PASSWORD] is the password
to be used for encrypting the returned content. [arg PASSWORD] itself
must be an empty string (if the returned data is not to be encrypted),
or the encryption password in 
[uri base.html#passwordprotection "encrypted form"] as returned
by the [uri base.html#read_credentials [cmd read_credentials]] or
[uri base.html#conceal [cmd conceal]] commands.
[nl]
The following options may be specified with the command:
[list_begin opt]
[opt_def [cmd -exportprivatekeys] [arg BOOLEAN]]
If [const true], any private keys associated with the exported certificates
are included in the returned binary. Default is [const false].
[opt_def [cmd -failonmissingkey] [arg BOOLEAN]]
If [const true], the command raises an error if any certificate claims
to have an associated private key but does actually have one.
 Default is [const false].
[opt_def [cmd -failonunexportablekey] [arg BOOLEAN]]
If [const true], the command raises an error if any certificate claims
to have an associated private key but does actually have one that is
exportable. Default is [const false].
[list_end]

[call [cmd cert_store_export_pkcs12] [arg HSTORE] [arg PASSWORD] [opt [arg options]]]
Alias for [uri #cert_store_export_pfx [cmd cert_store_export_pfx]].

[call [cmd cert_store_export_pkcs7] [arg HSTORE] [opt "[cmd -encoding] [arg ENCODING]"]]
Returns a binary in PKCS #7 format containing all the certificates 
in a certificate store.
[arg HSTORE] is a handle to the store. External properties associated
with certificate are not exported.
The [cmd -encoding] option
specifies the encoding for the returned certificate.
[arg ENCODING] should be [const der] or [const pem] (default)
for DER- and PEM-encoding respectively.

[call [cmd cert_store_find_certificate] [arg HSTORE] [opt [arg SEARCHTYPE]] [opt [arg SEARCHTERM]] [opt [arg HCERT]]]
The command returns a handle to a certificate context for 
the next matching certificate in the store specified by the handle
[arg HSTORE]. When [arg HCERT] is not specified or is specified as
[const NULL], the search starts from the first certificate in the store.
If [arg HCERT] is specified, it must be a handle to a certificate context
returned by a previous call to the command. The search then begins with
the next certificate in the store. The command also frees [arg HCERT]
(even in case of errors) so caller must not access it after the command
returns. If [arg HCERT] needs to be accessed later, use the
[uri #cert_duplicate [cmd cert_duplicate]] command to make a copy first.
[nl]
A certificate context handle returned by the command that is
not passed back in as [arg HCERT] in a subsequent call, must be released
by calling [uri #cert_release [cmd cert_release]].
[nl]
The command returns an
empty string when there are no more certificates in the store.
[nl]
The criteria for matching are specified by the [arg SEARCHTYPE] and
[arg SEARCHTERM] arguments as in the table below where the first column
specifies possible values of [arg SEARCHTYPE].
[list_begin opt]
[opt_def [const any]]
Returns every certificate in the store. [arg SEARCHTERM] is ignored.
[opt_def [const certificate]]
Returns certificates that exactly match the certificate context whose
handle is specified as [arg SEARCHTERM].
[opt_def [const issuer_name]]
Returns certificates whose issuer exactly matches [arg SEARCHTERM].
[arg SEARCHTERM] is a X.509 name in encoded form as returned
by [uri #cert_name_to_blob [cmd cert_name_to_blob]].
[opt_def [const issuer_substring]]
Returns certificates whose issuer contains the string [arg SEARCHTERM].
Note [arg SEARCHTERM] is a string, not in X.509 encoded form.
[opt_def [const key_identifier]] Returns certificates with a matching
value for the subject key identifier (OID [const 2.5.29.14]) extension.
[opt_def [const md5_hash]]
Returns certificates that have a MD5 hash which matches the binary [arg SEARCHTERM].
[opt_def [const property]]
Returns certificates that have a property with id [arg SEARCHTERM]
(see [uri #cert_property [cmd cert_property]]).
[opt_def [const pubkey_md5_hash]]
Returns certificates whose MD5-hashed public key matches the binary [arg SEARCHTERM]. The hash should be calculated over the public key in the format returned
by [uri crypto.html#crypt_key_export [cmd crypt_key_export]].
[opt_def [const public_key]]
Returns certificates containing the specified public key [arg SEARCHTERM].
This is a pair consisting of the algorithm identifier 
(in the same format as [const -signaturealgorithm]) and a binary
containing the public key. This binary should be in the format returned by
[uri crypto.html#crypt_key_export [cmd crypt_key_export]].
[opt_def [const sha1_hash]]
Returns certificates that have a SHA1 hash which matches the binary [arg SEARCHTERM].
[opt_def [const signature_hash]]
Returns certificates that have a signature hash which matches the binary [arg SEARCHTERM].
[opt_def [const subject_name]]
Returns certificates whose subject exactly matches [arg SEARCHTERM].
[arg SEARCHTERM] is a X.509 name in encoded form as returned
by [uri #cert_name_to_blob [cmd cert_name_to_blob]].
[opt_def [const subject_substring]]
Returns certificates whose subject contains the string [arg SEARCHTERM].
Note [arg SEARCHTERM] is a string, not in X.509 encoded form.

[list_end]

[call [cmd cert_store_release] [arg HSTORE]]
Decreases the reference count for the specified handle to a certificate store
and releases associated resources when it reaches 0.

[call [cmd cert_store_serialize] [arg HSTORE]]
Returns a binary containing all the certificates 
in a certificate store along with their external properties.
[arg HSTORE] is a handle to the store to be serialized. The returned
data may be stored in a file that can be opened with
[uri #cert_file_store_open [cmd cert_file_store_open]].


[call [cmd cert_subject_name] [arg HCERT] [opt [arg options]]]
Returns a subject name field from the certificate context [arg HCERT]. 
The field may be from the certificate itself or a certificate property
in the context.
[nl]
By default the common name in the certificate is returned.
The [cmd -name] option can be specified to retrieve a different field.
The value of the option can be a OID string identifying a certificate
name attribute or one of the values in the table below:
[list_begin opt]
[opt_def [const dns]] Returns the DNSName choice in the Alternative Name
extension if there is one, or the the CN OID [const 2.5.4.3] from the
Subject Name field. If neither is found returns an empty string.
[opt_def [const email]] Returns the first rfc822Name choice in 
the Alternative Name extension. If not found, returns the name field
for the Email OID. Otherwise returns an empty string.
[opt_def [const friendlydisplay]] Returns the [const CERT_FRIENDLY_NAME_PROP_ID]
property if there is one. Otherwise behaves as [cmd simpledisplay].
[opt_def [const simpledisplay]] Returns the first attribute suitable
for display purposes from
Name or Alternative Name extension.
[opt_def [const oid_common_name]] Returns the Common Name (Default).
[opt_def [const rdn]] Returns the Subject Name RDN if there is one.
If not found, returns the first Directory Name choice from
the Alternative Name extension if there is one. Otherwise returns
an empty string. The format for this option can be further controlled
as described later.
[opt_def [const upn]] Returns the UPN from the OID 
[const 1.3.6.1.4.1.311.20.2.3] in the OtherName choices from
the Alternative Name extension and an empty string if not found.
[opt_def [const url]] Returns the URL choice in the Alternative Name
extension if there is one. If not found, returns an empty string.
[list_end]

When the [cmd -name] option is [const rdn], the following options
may be further specified to control the returned format.
[list_begin opt]
[opt_def [cmd -format] [arg FORMAT]] Specifies how the output
is to be formatted. [arg FORMAT] must be one of [const x500] (default),
[const oid] or [const simple].
[opt_def [cmd -noplus] [arg BOOLEAN]] If [const true], the plus sign
in names is replaced with a single space. Default is [const false].
[opt_def [cmd -noquote] [arg BOOLEAN]] If [const true], quoting of
special characters in RDN names is disabled. Default is [const false].
[opt_def [cmd -reverse] [arg BOOLEAN]] If [const true], order of
RDN components is reversed. Default is [const false].
[opt_def [cmd -separator] [arg SEPARATOR]] Specifies the separator
to use between RDN components.
[arg SEPARATOR] must be one of [const comma] (default), [const semicolon]
or [const newline].
[list_end]
The command returns an empty string if the specified name does not exist in the
certificate.

[call [cmd cert_system_store_open] [arg NAME] [opt [arg LOCATION]] [opt [arg options]]]
Opens a logical system store and returns a handle to a cached copy.
[arg NAME] is the name of the logical store such as [const Root] or
[const My]. [arg LOCATION] specifies the location of the system store 
and must be one of
the values listed in [sectref "Certificate stores"].
[nl]
The following options may be specified:

[list_begin opt]

[opt_def [cmd -backupprivilege] [arg BOOLEAN]]
If [const true], specifies that the thread's [const SE_BACKUP_NAME]
and [const SE_RESTORE_NAME] privileges must be used to open the store.
Default is [const false].

[opt_def [cmd -create] [arg BOOLEAN]]
If [const true], a new store is opened only if it did not exist. An error
is raised if the store already existed.
Default is [const false] so no error is raised in the latter case.
[opt_def [cmd -deferclose] [arg BOOLEAN]]
Normally changes to any certificate contexts made after the associated store
is closed are not persisted. Setting this option to [const true] will
defer the closing of the store until all associated certificate contexts
have been released.
Default is [const false].
[opt_def [cmd -existing] [arg BOOLEAN]]
If [const true], when [arg PATH] does not already exist, it is not created.
An exception is raised instead.
Default is [const false].
[opt_def [cmd -includearchived] [arg BOOLEAN]]
By default, enumeration of certificates in a store will not include any
that are marked as archived. Setting this option to [const true] will
cause those certificates to be included.
Default is [const false].
[opt_def [cmd -maxpermissions] [arg BOOLEAN]]
If [const true], the store is opened with the maximum set of access permissions
possible.
Default is [const false].
[opt_def [cmd -readonly] [arg BOOLEAN]]
If [const true], the store is opened in read-only mode. 
Depending on the provider, the effect may be to either disallow all changes to
the store, or to allow changes to the in-memory cache but not persisting them.
Default is [const false].
[list_end]
The store must be closed with [uri #cert_store_release [cmd cert_store_release]]
when no longer needed.

[call [cmd cert_system_store_delete] [arg NAME] [arg LOCATION]]
Deletes a certificate system store.
[arg NAME] is the name of the store and
[arg LOCATION]
specifies its location which must be one of
the values listed in [sectref "Certificate stores"].

[call [cmd cert_system_store_locations] [arg LOCATION]]
Returns a list of system store locations. See [sectref "Certificate stores"].

[call [cmd cert_system_stores] [arg LOCATION]]
Returns a list of system stores at the system store location [arg LOCATION].
[arg LOCATION] specifies the location of the system store and must be one of
the values listed in [sectref "Certificate stores"].

[call [cmd cert_temporary_store] [opt [arg options]]]
Creates a temporary, non-persistent certificate store in memory
and returns a handle to it.
The store must be closed with [uri #cert_store_release [cmd cert_store_release]]
when no longer needed. All contents of the store are deleted when
it is closed. The [uri #cert_store_save [cmd cert_store_save]] command
can be used to save the contents to a persistent store if desired.
[nl]
By default, the created store is empty. The following 
[emph "mutually exclusive"] options may be specified to initialize the
store with certificates.
[list_begin opt]
[opt_def [cmd -pfx] [arg PFXBLOB]]
Initializes the temporary store with certificates imported from
a PFX (also known as PKCS #12) formatted packet. In addition to the
certificates, any private keys present are also imported into the
system. Unlike the store itself, these keys are persisted. The following
additional options may be used with [cmd -pfx] and [cmd -pkcs12]:
[list_begin opt]
[opt_def [cmd -exportableprivatekeys] [arg BOOLEAN]]
If specified as [const true], private keys in the created certificate
store may be exported. Default is [const false].
[opt_def [cmd -keysettype] [const user|machine]]
Without this option, keys are imported as per-user or per-machine
as specified in the PFX blob. This option can be used to override this.
[opt_def [cmd -password] [arg PASSWORD]]
Specifies the password used to decrypt [arg PFXBLOB]. If the
option is not specified, or if [arg PASSWORD] is the empty string,
the command assumes [arg PFXBLOB] is in unencrypted
form. If not the empty string,
[arg PASSWORD] must be in
[uri base.html#passwordprotection "encrypted form"] as returned by
by the [uri base.html#read_credentials [cmd read_credentials]] or
[uri base.html#conceal [cmd conceal]] commands.
[opt_def [cmd -userprotected] [arg BOOLEAN]]
If specified as [const true], the private keys are protected such that
the user is notified on operations that use that key. The specific
operations that will trigger notifications depend on the CSP being used.
[list_end]
[opt_def [cmd -pkcs12] [arg PKCS12BLOB]]
This an alias for the [cmd -pfx] option.
[opt_def [cmd -pkcs7] [arg PKCS7BLOB]]
[arg PKCS7BLOB] is a PKCS #7 packet containing certificates. The additional
option "[cmd -encoding] [arg ENCODING]" may be used with [cmd -pkcs7]
where [arg ENCODING] may be [const der], or [const pem] to
indicate the packet is DER- or PEM-encoded. If unspecified, the
command will attempt to guess the encoding.
[opt_def [cmd -serialized] [arg SERIALIZEDBLOB]]
[arg SERIALIZEDBLOB] is a serialized certificate store,
such as returned from [uri #cert_store_serialize [cmd cert_store_serialize]].
[list_end]

The temporary store must be closed with
[uri #cert_store_release [cmd cert_store_release]]
when no longer needed.

[call [cmd cert_thumbprint] [arg HCERT]]
Returns a SHA-1 based thumbprint for the specified certificate.
This is returned as a hexadecimal string and can be used for
a quick comparison to check if two certificates are identical.

[call [cmd cert_tls_verify] [arg HCERT] [opt [arg options]]]
Verifies a certificate context [arg HCERT] for use
in a SSL/TLS connection. This is just a wrapper around
[uri #cert_verify [cmd cert_verify]] for backward compatibility
with the [arg POLICY] argument to that command hardcoded to [const tls]. 

[call [cmd cert_verify] [arg HCERT] [arg POLICY] [opt [arg options]]]
Verifies a certificate context [arg HCERT] for a specified purpose
as defined by [arg POLICY] which must have one of the values shown
below.

[list_begin opt]
[opt_def [const authenticode]]
Verifies the certificate for Authenticode use.
[opt_def [const authenticodets]]
Verifies the certificate for Authenticode Time Stamp policy.
[opt_def [const base]]
Implementes the base chain policy verification checks.
[opt_def [const basicconstraints]]
Checks the basic constraints policy. This relates to whether
certificates are constrained to be end entity certificates or certificate
authority certificates.
[opt_def [const extendedvalidation]]
Does extended validation of certificates. Requires Windows 7 or later.
[opt_def [const microsoftroot]]
Checks if the root element is a Microsoft root public key.
[opt_def [const ntauth]]
Verifies the Windows NT authentication policy.
[opt_def [const tls]]
Verifies the certificate for use in SSL/TLS connections.
[list_end]


The following options may be specified for all [arg POLICY] values:

[list_begin opt]
[opt_def [cmd -cacheendcert] [arg BOOLEAN]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -disableauthrootautoupdate] [arg BOOLEAN]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -engine] [arg ENGINE]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -hstore] [arg HSTORE]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -ignoreerrors] [arg ERRORLIST]]
Specifies that certain errors in verification are to be ignored.
See description later.

[opt_def [cmd -revocationcheck] [arg REVOCATIONSPEC]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -revocationcheckcacheonly] [arg BOOLEAN]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -trustedroots] [arg HCERTLIST]]
Windows requires the root of the certificate verification
chain belong to one the Windows' trusted stores. Under some circumstances,
such as use of a private certificate authority whose root certificate is
not in the Windows trusted store list, the command will return
a status of [const untrustedroot]. Instead of ignoring this error
through the [cmd "-ignoreerrors unknownca"] option, the caller
can provide a list of certificate contexts [arg HCERTLIST] 
that are acceptable as trusted root certificates [emph "in addition"] to
those in the Windows trusted store.

[opt_def [cmd -urlretrievalcacheonly] [arg BOOLEAN]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -usageall] [arg USAGELIST]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[opt_def [cmd -usageany] [arg USAGELIST]]
See [uri #cert_chain_build [cmd cert_chain_build]].

[list_end]

If [arg POLICY] is [const tls], the option [cmd -server]
may be specified. If specified, the verification is done assuming the
certificate is a server certificate and the corresponding option value
is the name of the server which must match the certificate. If this
option is not specified, the certificate is assumed to be a client-side
certificate and no name verification is done. Moreover,
if neither of the options [cmd -usageall] or [cmd -usageany] is explicitly
specified, they default to [const server_auth] and [const client_auth]
respectively depending on whether [cmd -server] is specified or not.
[nl]
If [arg POLICY] is [const basic_constraints] or [const nt_auth],
the option [cmd -isa] may be specified. This may take one of the values
[const ca] or [const endentity] indicating whether the certificate.
If the option is not specified, the certificate may either be for a CA or an
end entity. Otherwise, it must match the value specified for the option.

[nl]
If [arg POLICY] is [const authenticode] or [const authenticodets]
and neither [cmd -usageall] nor [cmd -usageany] is specified,
they default to [const code_signing].

[nl]
If [arg POLICY] is [const microsoft_root], the additional option
[cmd -enabletestroot] may be specified. The corresponding value
is a boolean (default [const false]) which indicates whether the
Microsoft test root should be included in addition to the Microsoft
public roots.

[nl]
The [cmd -ignoreerrors] option allows the caller to specify
certain error types that are to be ignored in the verification process.
[emph "This option must be used with great care and only in special circumstances."] The argument to the option is a list with one or more of the
following values:
[list_begin opt]
[opt_def [const basicconstraints]] Ignore errors in basic constraints.
[opt_def [const criticalextensions]] Ignore errors pertaining to
extensions marked as critical that are not understood by CryptoAPI.
[opt_def [const name]] Ignore errors in name validation.
[opt_def [const policy]] Ignore invalid policy errors.
[opt_def [const revocation]] Ignore errors related to certificate revocation.
[opt_def [const time]] Ignore errors in validity period checks.
[opt_def [const unknownca]] Allow the root certificate to not
be in the trusted roots list.
[opt_def [const usage]] Ignore errors related to the [cmd -usageall]
and [cmd -usageany] options.
[list_end]
The command returns [const ok] if the certificate was verified
successfully. If the certificate verification [emph process] could
not be executed, a Tcl exception is raised. If the verification
process completed but the certificate did not successfully pass,
the command does not raise an exception but returns a Win32 error
code or one of the following values:
[list_begin opt]
[opt_def [const signature]] Signature verification failed.
[opt_def [const revoked]] Certificate has been revoked.
[opt_def [const untrustedroot]] The root certificate is not a trusted root.
[opt_def [const partialchain]] The certificate chain does not end
in a self-signed certificate.
[opt_def [const wrongusage]] Certificate usage extension did not
match specified usage.
[opt_def [const time]] Certificate has expired or the validity time
is in the future.
[opt_def [const name]] Name does not match.
[opt_def [const policy]] Certificate did not match policy conditions.
[opt_def [const basicconstraints]] Basic constraints check failed.
[opt_def [const criticalextension]] Certificate includes an unsupported
extension marked as critical.
[opt_def [const validityperiodnesting]] Time periods for certificates
in the chain are not nested.
[opt_def [const norevocationcheck]] Revocation status of one of the
certificates in the chain is unknown.
[opt_def [const revocationoffline]] Revocation checks could not be done
because the revocation server was offline.
[opt_def [const cnmatch]] Common name does not match [cmd -server]
option.
[opt_def [const purpose]] The specified purpose is different from
the one specified by the issuing CA.
[opt_def [const carole]]
The certificate that can be marked for use as a CA is being used
as a leaf or vice-versa.
[list_end]

[list_end]

[keywords certificate "certificate store" key cryptography encryption decryption CryptoAPI PKCS]

[manpage_end]
