Library
Module
Module type
Parameter
Class
Class type
an OCaml version of Openssl's NCONF library
Version 0.8.3 — homepage
Module Sslconf
: a parser for Openssl config files.
Openssl config file documentation: config.html
Openssl config files are ubiquitous in books, in documentation, and in Stack Overflow answers.
Definition of X509 certificates in Openssl is usually done by Openssl config files.
This module reproduces the Openssl NCONF implementation. Openssl NCONF is part of the Openssl crypto library (-libcrypto).
This module attaches no semantics to the strings and stacks it returns. It is similar to Openssl NCONF in this way.
Openssl attaches semantics to the CONF data structure returned by Openssl NCONF, via commands such as openssl x509 or openssl ca.
This implementation is backed by standard OCaml hash tables and stacks. Some may view this as a weakness. Openssl's NCONF implementation draws on custom hash tables and stacks defined in Openssl's crypto library.
Openssl code: conf.h conf_def.c conf_api.c conf_lib.c bss_fd.c
Lines recognized by the parser are:
comment lines, i.e.,
';'
) before non-white-space; or'#'
), then arbitrary data;section lines, i.e.,
"[<section>]"
) string inside square brackets; orvalue lines, i.e.,
"<name> = <value>"
) assignment.Openssl config file documentation: config.html
The Openssl config file documentation is enough for most users, but is not a complete specification.
What follows is detail for maintainers.
If the parser sees an escape char ('\\'
) at the end of a line, it combines the line with the next line.
The escape char may itself be escaped. If escaped, the escape char loses its special meaning as a line continuation mark.
The parser reads up to a newline, or a maximum length if no newline is found. If no newline is found, the parser does another read, and so on, until a newline is found or end of file is is detected.
The max number of characters the parser reads in one read is 510. This number is dictated by a need for C code to put null bytes in a 512 byte buffer.
This implementation follows the 510 char rule. A config file valid in Openssl will still be valid here.
If the parser sees an escape char ('\\'
) at the end of a read, i.e., as the 510th character, it will apply line continuation logic -- even if a newline is not seen at the end.
Both newlines and line continuation characters are removed from the strings passed to the parser in its second pass.
Error reporting reports line and column numbers. Line numbers are relative to the file being read.
The first line is line 1. The first column is column 1.
A comment line is either an empty line, a line of all whitespace, or whitespace followed by a hash char.
In Win32 only, a line starting with a semicolon is also a comment.
Comment lines are ignored and not saved.
The end of a value line may have a comment. Value line comments start with a hash char. Any text up to end of line can follow the hash char.
A section line has a ("[<section>]"
) string surrounded by square brackets. The string names a section.
Whitespace is trimmed from both ends of the string.
A section may contain alphanumerics, underscores, punctuation, or whitespace.
Alphanumerics are any letter (from 'a'
to z
or 'A'
to 'Z'
) or a number (from '0'
to '9'
).
Underscores are one or more underscore ('_') characters.
Punctuation is one or more of the following characters: ('!'
, '.'
, '%'
, '&'
, '*'
, '+'
, ';'
, '?'
, '@'
, '^'
, '~'
, '|'
, or '-'
).
A section may also contain escaped characters. An escaped character immediately follows an escape ('\\'
) char. Any character may be an escaped character.
If an escaped character is ('r'
, 'n'
, 'b'
, or 't'
), it is translated into a whitespace char ("\r", "\n", "\b", or "\t"
). Otherwise, it is retained as is.
Escape chars are stripped out from a section. Escaped chars therefore appear in section names as if they were not escaped.
The section named in a section line becomes the default section for lines which follow. It remains the default until a new section line is read.
A line with a ("<name> = <value>"
) assignment is a value line. A value line always has a name, an equal sign, and a value. Whitespace before or after the equal sign is optional.
A value line assigns a value to a name in a section.
Lexical rules for a name (qualified or unqualified) are more restrictive than for a section in a section line.
Whitespace is trimmed from both ends of a name.
A name may contain alphanumerics, underscores, and punctuation. A name may not contain whitespace.
As with section names, escaped characters are allowed. An escaped character immediately follows an escape ('\\'
) char. Any character may be an escaped character.
Unlike with section names, escape chars are not stripped. An escape char goes in the hash table as part of a name.
A name can be qualified or unqualified.
A qualified name splits into two parts, separated by a two-colon string ("::"
). The first part of a qualified name is the section. The second part is the name.
If the section of a qualified name is not in the hash table, a new entry for the section is added.
An unqualified name belongs to the default section. The default section is the section named by the most recent previous section line, or "default" if no section line has occured yet.
A value is a sequence of parts, starting with the first non-whitespace character after the equal sign on a value line.
A part is one of three kinds:
Whitespace is stripped from the start and end of a value. Whitespace following the equal sign, and whitespace, either to the end of a line, or up to a comment hash char if present, is ignored.
Unix and Cygwin use default quote wrapping.
Default quote wrapped parts accept any character as is, and also allow quotes if preceded immediately by escape chars.
Escape chars and the quotes which wrap surrounded parts are stripped.
Win32 uses double quote wrapping. Double quote wrapped parts accept any character as is, unless it is a double quote. There is one exception. A double quote may appear inside a double quote wrapped string, if a double quote immediately precedes it.
Wrapping double quotes, and double quotes which immediately precede double quotes, are stripped.
Name substitution starts with a ('$'
) character. The ('$'
) character should be followed by a name. The name may be optionally wrapped by parentheses ("()"
) or curly brackets ("{}"
). The subst
evaluator replaces the ('$'
), the optional wrapping, and the name with the value corresponding to the name and its section.
If the section is not ("ENV"
), a value is found from a hashtable with section+name keys. If the section is ("ENV"
), a value is found from the process environment.
If substitution fails, the parser returns an error, reporting that no value could be found for the name.
A name given for name substitution may only contain alphanumeric or underscore characters. It may not contain punctuation or whitespace, unless these are escaped via an escape ('\\'
) character. If an escaped character is in a name, its escape char is retained, along with the escaped character in the name.
Regular text accepts any character other than single quotes, double quotes, or the ('$'
) substitution character.
It may still have
Regular text can have escaped characters. An escaped character immediately follows an escape ('\\'
) char.
If an escaped character is ('r'
, 'n'
, 'b'
, or 't'
), it is translated into a whitespace char ("\r", "\n", "\b", or "\t"
). If it is not one of these characters, it is retained as is.
The special meanings of escaped characters are cancelled. For example, one can precede a double quote by an escape char, to cancel its usual meaning of starting a quote-wrapped part.
Escape chars are stripped. They don't appear in hash table values. Escaped characters remain.
An unescaped hash ('#'
) char starts a comment to end of line. Any data following the hash char, up to the end of a line, is ignored.
Characters not belonging to wrapped segments or name substitutions can be any character. For example, whitespace can occur in the middle of a value.
module Buf : sig ... end
Sslconf buffer.
module Bio : sig ... end
Basic I/O.
val create : unit -> t
Initialize an Sslconf instance
val nbits : int option ref
FOR TESTING ONLY
Limits buffer allocated memory to a max bit length.
type error =
| Open of string
| Extend of string * int * int * int
| Parse of string * int * int * string * string
Open (msg):
Extend (msg nbits max_length max_alloc):
Parse (file lineno col proc msg):
val string_of_error : error -> string
string_of_error error
converts an error to a user-readable string.
val conf_load_file : t -> string -> (unit, error) Rresult.result
conf_load_file conf filename
loads a file into a t
instance. The error instance describes only the first failure found.
val conf_get_value : ?conf:t -> ?section:string -> string -> string option
conf_get_value ?conf ?section name
gets an optional value from a name. A string option is returned.
See Openssl NCONF_get_string()
in conf_lib.c. If a config instance is provided, its hash table with section+name keys is searched. If no config instance is provided, the process environment is searched. If a section is provided, then:
"ENV"
, the process environment is searched.If no section is provided, or the search in a provided section fails, then section "default" is used with the name.
type stack = (string * string) Stack.t
A stack with (name, value) entries.
conf_get_section conf section
gets an optional stack of name-value pairs.
See Openssl function NCONF_get_section()
in conf_lib.c. A hash table with section names in the config instance is searched for a section. If a stack is returned, and <name> is in a name-value pair on it, then conf_get_value conf section name
will get its most recent value.
val sexp_of_stack : stack -> Sexplib.Sexp.t
sexp_of_stack conf section
converts a config instance section stack to an s-expression
val stack_of_sexp : Sexplib.Sexp.t -> stack
stack_of_sexp sexp
converts an s-expression to a config instance section stack
val sexp_of_conf : t -> Sexplib.Sexp.t
sexp_of_conf conf
converts a config instance to an s-expression
val conf_of_sexp : Sexplib.Sexp.t -> t
conf_of_sexp sexp
converts an s-expression to a config instance