For SASL credentials are specified as a list
(string * string * (string * string) list) list
which looks complicated and needs some explanations. Basically, this list presents the authentication mechanism a number of encodings for the same secret. The mechanism can then pick the encoding it can process best. Every encoding of the secret is a tuple
(type, data, params)
data are strings, and
params is a
(string * string) list) list with
Why supporting several encodings? First, there may be huge differences in
the speed of the authentication mechanism, in particular when you compare
a cleartext password
pw with the version of
pw that is really used in
the mechanism, which is often a function of the password
kdf(pw) (kdf =
key derivation function). These functions are designed to be slow.
Second, there may be a security benefit when a password database needs not
pw, but can store
kdf(pw), in particular on the server side.
All mechanisms support:
type = "password": The
datastring is the raw, unprocessed password. Note that many mechanisms require that the password is a UTF-8 string, and some even request a certain UTF-8 form (the so-called string preparation of the password). The password type does not take any parameters.
The other types are mechanism-specific, and are usually only supported on the server side:
type = "authPassword-SCRAM-SHA-1": The
datastring is the "stored password" for the mechanism SCRAM-SHA-1. There is one parameter "info" containing the iteration count and the salt. These two strings are defined in RFC-5803. OCamlnet uses here intentionally the same format as is commonly used in LDAP servers for storing SCRAM credentials. See
Netmech_scram_sasl.SCRAMfor sample code how to generate this encoding.
(This list will probably be extended.)
OCamlnet tries to support types conforming either to the pattern defined
in RFC 3112 or RFC 2307. See
Netsys_sasl_types.SASL_MECHANISM.init_credentials for details.
All user names and passwords for SASL mechanisms must be given in UTF-8.
Moreover, there is a special algorithm normalizing characters where
Unicode permits several ways of encoding them: SASLprep. In OCamlnet,
SASLprep is implemented by
Newer SASL mechanisms require that user names and passwords go through SASLprep. Although older mechansims do not strictly require this yet, it is often also a good idea to apply SASLprep nevertheless, as all mechanisms access the same password database.
OCamlnet does not automatically call SASLprep. Callers of the SASL mechanisms should do that before the user names and passwords reach the mechanism implementations, e.g.
let creds = [ "password", Netsaslprep.saslprep pw,  ]
The reason is that SASLprep is fairly expensive, and should best only called once when several mechanisms have been enabled.
The (X.509) credentials exist here in two "flavors", namely certificates and private keys.
What makes the handling of these data structures a bit problematic are the various encodings and container formats. Usually certificates and keys are stored on disk, where key files are often password-protected. But one step after the other:
Representations in RAM
Netx509.x509_certificateobjects. The parser function is
`DERis also used for these lists. There is, however, no parser callable from OCaml. (Inside GnuTLS there is a parser.)
`PKCS8_encryptedare attached to strings with the respective formats. As of now, no parsers for any of these formats are callable from OCaml. Important note: Encrypted keys are only supported via PKCS-8. If you have a PEM file with a "DEK-Info" header, this file cannot be read in. Convert it to PKCS-8 first with an external tool.
Representations on disk
As mentioned, there is always a container format:
Netascii_armor. These are the objects (per header string):
Note that OCamlnet does not contain any utility for generating these
files. You can use the GnuTLS utility
certtool or the
Besides X.509 credentials, there are also other types (e.g. SRP or OpenPGP credentials) that be used with TLS. This is quite uncommon, though, and should only be used in special situations. At present, such alternate authentication methods are not supported in these TLS bindings.
You can usually pass credentials as pairs
string * oid where the
string contain the data formatted according to the rules for the OID.
At present, there are no helper functions to support any type of OID better that is possible here.
To be written