# Credentials

### Credentials for SASL

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)

where `type` and `data` are strings, and `params` is a `(string * string) list) list` with `(name,value)` pairs.

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 to store `pw`, but can store `kdf(pw)`, in particular on the server side.

All mechanisms support:

- `type = "password"`: The `data` string 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 `data` string 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.SCRAM` for 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.

#### UTF-8

All user names and passwords for SASL mechanisms must be given in UTF-8.

#### SASLprep

Moreover, there is a special algorithm normalizing characters where Unicode permits several ways of encoding them: SASLprep. In OCamlnet, SASLprep is implemented by `Netsaslprep`.

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.

### Credentials for TLS

The (X.509) credentials exist here in two "flavors", namely certificates and private keys.

- A certificate is a public key that is signed by a trust center. In order to be exact, we should also take the revocations into account, present in form of CRLs (certificate revocation lists).
- A private key is a large random number.

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

- DER encoding of certificates: This is the primary way certificates are represented as binary BLOB. The DER encoding is not directly used for storing certificates in files. In OCamlnet, the DER encoding is a string (or string list) tagged with ``DER`.
- Certificates as parsed objects: The DER encoding can be parsed, and their contents are made accessible as `Netx509.x509_certificate` objects. The parser function is `Netx509.x509_certificate_from_DER`.
- DER encoding of CRLs: Like for certificates there is a DER encoding for revocation lists. The tag ``DER` is also used for these lists. There is, however, no parser callable from OCaml. (Inside GnuTLS there is a parser.)
- Private keys can exist in various encodings: RSA, DSA, EC, and PKCS-8. These are also binary encodings based on ASN.1, but with a different internal format. The formats for RSA, DSA, and EC are for the respective public key mechanisms. PKCS-8 is a container format that can contain any of these formats internally, and that optionally also supports encryption. In OCamlnet, the tags ``RSA`, ``DSA`, ``EC`, ``PKCS8` and ``PKCS8_encrypted` are 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:

- PEM files: These text files are made up of sections, and every section consists of a header like "-----BEGIN CERTIFICATE-----", the base64 encoded data, and a trailer like "-----END CERTIFICATE-----". Various types of objects are supported. There is a generic parser for the PEM format in `Netascii_armor`. These are the objects (per header string):
  - "X509 CERTIFICATE" or "CERTIFICATE": The data is the DER encoding of the certificate
  - "X509 CRL": The data is the DER encoding of the CRL
  - "RSA PRIVATE KEY": The data is the RSA key
  - "DSA PRIVATE KEY": The data is the DSA key
  - "EC PRIVATE KEY": The data is the EC key
  - "PRIVATE KEY": The data is in PKCS-8 format
  - "ENCRYPTED PRIVATE KEY": The data is in the encrypted PKCS-8 format
- PKCS-12 files: so far unsupported in OCamlnet

Note that OCamlnet does not contain any utility for generating these files. You can use the GnuTLS utility `certtool` or the `openssl` command.

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.

### Credentials for the GSSAPI

#### The system-level GSSAPI

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.

#### GSSAPI modules defined in OCaml

To be written