Ocamlnet 3 Reference Manual : Netgssapi

# Module Netgssapi

    module Netgssapi: sig .. end

GSS-API Definition

This is mainly a translation of RFC 2743/2744 to Ocaml.

## Types

    type oid = int array

OIDs like "1.3.6.1.5.6.2" as array of int's. The empty array means `GSS_C_NO_OID`.

    type oid_set = oid list

A set of OID's. These lists should not contain OID's twice. The empty list means `GSS_C_NO_OID_SET`.

    type credential = < otype : [ `Credential ] >

A credential is opaque for the caller of the GSS-API. The provider of the GSS-API can emit new credential objects, and hand them out to the caller. When the caller passes credentials back to the provider, the provider must check whether the object is known, and reject any fake objects created by the caller by raising `Invalid_argument`.

    type context = < otype : [ `Context ]; valid : bool >

A context is also opaque, and the same rules apply as for `credential`.

The method `valid` is true as long as the context is not deleted.

    type token = string

Authentication tokens. These are also opaque to the caller, but have a string representation so that they can be sent over the wire.

    type interprocess_token = string

Interprocess tokens. These are also opaque to the caller, but have a string representation so that they can be sent over the wire.

    type calling_error = [ `Bad_structure | `Inaccessible_read | `Inaccessible_write | `None ]

Possible errors caused by the caller

    type routine_error = [ `Bad_QOP
           | `Bad_bindings
           | `Bad_mech
           | `Bad_mic
           | `Bad_name
           | `Bad_nametype
           | `Bad_status
           | `Context_expired
           | `Credentials_expired
           | `Defective_credential
           | `Defective_token
           | `Duplicate_element
           | `Failure
           | `Name_not_mn
           | `No_context
           | `No_cred
           | `None
           | `Unauthorized
           | `Unavailable ]

Possible errors caused by the provider

    type suppl_status = [ `Continue_needed
           | `Duplicate_token
           | `Gap_token
           | `Old_token
           | `Unseq_token ]

Further flags

    type major_status = calling_error * routine_error *
           suppl_status list

The major status consists of these three elements. The bits of the supplementary status field are represented as list

    type minor_status = int32

The minor status is provider-specific. Note that GSS-API defines it as unsigned 32-bit integer whereas `int32` is signed.

    type name = < otype : [ `Name ] >

A name is also opaque, and the same rules apply as for `credential`.

    type address = [ `Inet of Unix.inet_addr
           | `Local of string
           | `Nulladdr
           | `Other of int32 * string
           | `Unspecified of string ]

Addresses tagged by address types

    type channel_bindings = address * address * string

Channel binding as tuple `(initiator_address, acceptor_address, application_data)`

    type cred_usage = [ `Accept | `Both | `Initiate ]

    type qop = < otype : [ `QOP ] >

Quality-of-proctection parameters are mechanism-specific

    type message = Xdr_mstring.mstring list

Messages are represented as lists of `mstring`

    type ret_flag = [ `Anon_flag
           | `Conf_flag
           | `Deleg_flag
           | `Integ_flag
           | `Mutual_flag
           | `Prot_ready_flag
           | `Replay_flag
           | `Sequence_flag
           | `Trans_flag ]

Flags for the `accept_sec_context` method

    type req_flag = [ `Anon_flag
           | `Conf_flag
           | `Deleg_flag
           | `Integ_flag
           | `Mutual_flag
           | `Replay_flag
           | `Sequence_flag ]

Flags for the `init_sec_context` method

## Exceptions

There are no defined exceptions.

Errors should be reported using the `major_status` and `minor_status` codes as much as possible.

`Invalid_argument` may be raised for clear violations of calling requirements, e.g. when an opaque object is passed to this interface that was not returned by it before.

## The API

The methods have generally a type of the form

           m : 't . arg1 -> ... -> argN -> out:( ret1 -> ... -> retM -> 't ) -> 't

where `arg`s are input arguments (with the exception of `context` which is in/out), and where outputs are passed back by calling the `out` functions with the outputs. The return value of `out` is the return value of the method call.

For example, if only `output_token` of the `accept_sec_context` method is needed, one could call this method as in

          let output_token =
    	gss_api # accept_sec_context
    	   ...
    	   ~out:(fun ~src_name ~mech_type ~output_token ~ret_flags
    		     ~time_rec ~delegated_cred_handle ~minor_status
    		     ~major_status ->
    		  output_token
    		)

Output values may not be defined when `major_status` indicates an error. (But see the RFC for details; especially `init_sec_contect` and `accept_sec_context` may emit tokens even when `major_status` indicates an error.)

The names of the parameters are taken from RFC 2744, only suffixes like `_handle` have been removed. When the prefixes `input_` and `output_` are meaningless, they are also removed. All prefixes like "GSS" are removed anyway.

    class type gss_api = object .. end

## Utility functions

These functions convert values to strings. Useful for generating log messages.

    val string_of_calling_error : calling_error -> string

    val string_of_routine_error : routine_error -> string

    val string_of_suppl_status : suppl_status -> string

    val string_of_major_status : major_status -> string

## Common OID's for name types

See RFC 2078, section 4

    val nt_hostbased_service : oid

names like "service

    val nt_user_name : oid

names like "username"

    val nt_machine_uid_name : oid

user ID in host byte order

    val nt_string_uid_name : oid

user ID as string of digits

    val nt_anonymous : oid

anonymous name

    val nt_export_name : oid

an export name

    val parse_hostbased_service : string -> string * string

Returns (`service,host`) for "service

## Encodings

There is some chance that some of these routines will finally be moved to netstring

    val oid_to_string : oid -> string

    val string_to_oid : string -> oid

Convert OID's to/from curly brace notation

    val oid_to_der : oid -> string

    val der_to_oid : string -> int Pervasives.ref -> oid

Convert OID's to/from DER. `der_to_oid` takes a cursor as second arg.

    val wire_encode_token : oid -> token -> string

    val wire_decode_token : string -> int Pervasives.ref -> oid * token

Encode tokens as described in section 3.1 of RFC 2078. This is usually only done for the initiating token.

    val encode_exported_name : oid -> string -> string

    val decode_exported_name : string -> int Pervasives.ref -> oid * string

Encode names as described in section 3.2 of RFC 2078

## Create tokens

Format of the tokens: see RFC 4121

    val create_mic_token : sent_by_acceptor:bool ->
           acceptor_subkey:bool ->
           sequence_number:int64 ->
           get_mic:(message -> string) -> message:message -> string

Create a MIC token:

- `sent_by_acceptor`: whether this token comes from the acceptor
- `acceptor_subkey`: see RFC
- `sequence_number`: a sequence number
- `get_mic`: the checksum function (e.g. `Netmech_scram.Cryptosystem.get_mic`)
- `message`: the message to be signed

The function returns the MIC token

    val parse_mic_token_header : string -> bool * bool * int64

Returns the triple (`sent_by_acceptor`, `acceptor_subkey`, `sequence_number`) from the header of a MIC token that is passed to this function as string. Fails if not parsable

    val verify_mic_token : get_mic:(message -> string) ->
           message:message -> token:string -> bool

Verifies the MIC `token` with `get_mic`, and returns true if the verification is successful

    val create_wrap_token_conf : sent_by_acceptor:bool ->
           acceptor_subkey:bool ->
           sequence_number:int64 ->
           get_ec:(int -> int) ->
           encrypt_and_sign:(message -> message) ->
           message:message -> message

Wraps a `message` so that it is encrypted and signed (confidential).

- `sent_by_acceptor`: whether this token comes from the acceptor
- `acceptor_subkey`: see RFC
- `sequence_number`: a sequence number
- `get_ec`: This function returns the "extra count" number for the size of the plaintext w/o filler (e.g. use `Netmech_scram.Cryptosystem.get_ec`).
- `encrypt_and_sign`: the encryption function from the cryptosystem. The plaintext is passed to this function, and the ciphertext with the appended signature must be returned in the string.
- `message`: the payload message

The function returns the token wrapping the message.

    val parse_wrap_token_header : message -> bool * bool * bool * int64

`let (sent_by_acceptor, sealed, acceptor_subkey, sequence_number) = parse_wrap_token_header token`

Fails if the `token` cannot be parsed.

    val unwrap_wrap_token_conf : decrypt_and_verify:(message -> message) ->
           token:message -> message

Unwraps the `token` using the decryption function `decrypt_and_verify` from the cryptosystem.

The functions fails if there is a format error, or the integrity check fails.

Non-confidential messages cannot be unwrapped with this function.

Token functions for non-confidential messages are still missing