object

# `http_digest`

HTTP Digest authentication parsing, generation, request decoration, and verification helpers.

Availability:
`logtalk_load(http_digest(loader))`
Author: Paulo Moura
Version: 1:0:0
Date: 2026-07-07
Compilation flags:
`static, context_switching_calls`
Imports:
`public` options
`public` http_text_helpers
Uses:
crypto
date
hmac
http_core
list
os
sha256
user
Remarks:
(none)
Inherited public predicates:
check_option/1 check_options/1 default_option/1 default_options/1 option/2 option/3 valid_option/1 valid_options/1

## Public predicates

### `challenge/2`

Returns the single parsed Digest `WWW-Authenticate` challenge from a normalized HTTP response when present.

Compilation flags:
`static`
Template:
`challenge(Response,Challenge)`
Mode and number of proofs:
`challenge(+compound,-compound)` - `zero_or_one`

### `authorization/2`

Returns the single parsed Digest `Authorization` header from a normalized HTTP request when present.

Compilation flags:
`static`
Template:
`authorization(Request,Authorization)`
Mode and number of proofs:
`authorization(+compound,-compound)` - `zero_or_one`

### `authentication_info/2`

Returns the parsed `Authentication-Info` header from a normalized HTTP response when present.

Compilation flags:
`static`
Template:
`authentication_info(Response,AuthenticationInfo)`
Mode and number of proofs:
`authentication_info(+compound,-compound)` - `zero_or_one`

### `parse_challenge/2`

Parses one Digest challenge header field value into a normalized `digest_challenge/1` term.

Compilation flags:
`static`
Template:
`parse_challenge(Text,Challenge)`
Mode and number of proofs:
`parse_challenge(++text,-compound)` - `one_or_error`
Exceptions:
`Text` is neither a variable nor text:
`type_error(text,Text)`
`Text` is not a valid Digest challenge header value:
`domain_error(http_digest_header(www_authenticate),invalid(syntax))`
`Text` uses an unsupported authentication scheme:
`domain_error(http_digest_header(www_authenticate),unsupported_scheme(Scheme))`
`Text` contains a duplicated Digest challenge directive:
`domain_error(http_digest_header(www_authenticate),duplicate(Name))`
`Text` contains an unexpected Digest challenge directive:
`domain_error(http_digest_header(www_authenticate),unexpected(Name))`
`Text` is missing a required Digest challenge directive:
`domain_error(http_digest_header(www_authenticate),missing(Name))`
`Text` contains an invalid Digest challenge directive value:
`domain_error(http_digest_header(www_authenticate),invalid(Name))`

### `generate_challenge/2`

Generates one canonical Digest challenge header field value from a normalized `digest_challenge/1` term.

Compilation flags:
`static`
Template:
`generate_challenge(Challenge,HeaderValue)`
Mode and number of proofs:
`generate_challenge(+compound,-atom)` - `one_or_error`
Exceptions:
`Challenge` is not a valid normalized Digest challenge term:
`domain_error(http_digest_term(challenge),Challenge)`
`Challenge` is missing a required field:
`domain_error(http_digest_term(challenge),missing(Name))`
`Challenge` contains a duplicated field:
`domain_error(http_digest_term(challenge),duplicate(Name))`
`Challenge` contains an unexpected field:
`domain_error(http_digest_term(challenge),unexpected(Name))`
`Challenge` contains an invalid field:
`domain_error(http_digest_term(challenge),invalid(Name))`
`Challenge` fields are not in canonical order:
`domain_error(http_digest_term(challenge),invalid_order)`
`Challenge` contains an invalid algorithm:
`domain_error(http_digest_algorithm,Algorithm)`
`Challenge` contains an invalid qop value:
`domain_error(http_digest_qop,Qop)`
`Challenge` contains an invalid charset:
`domain_error(http_digest_charset,Charset)`

### `parse_authorization/2`

Parses one Digest authorization header field value into a normalized `digest_authorization/1` term.

Compilation flags:
`static`
Template:
`parse_authorization(Text,Authorization)`
Mode and number of proofs:
`parse_authorization(++text,-compound)` - `one_or_error`
Exceptions:
`Text` is neither a variable nor text:
`type_error(text,Text)`
`Text` is not a valid Digest authorization header value:
`domain_error(http_digest_header(authorization),invalid(syntax))`
`Text` uses an unsupported authentication scheme:
`domain_error(http_digest_header(authorization),unsupported_scheme(Scheme))`
`Text` contains a duplicated Digest authorization directive:
`domain_error(http_digest_header(authorization),duplicate(Name))`
`Text` contains an unexpected Digest authorization directive:
`domain_error(http_digest_header(authorization),unexpected(Name))`
`Text` is missing a required Digest authorization directive:
`domain_error(http_digest_header(authorization),missing(Name))`
`Text` contains an invalid Digest authorization directive value:
`domain_error(http_digest_header(authorization),invalid(Name))`

### `generate_authorization/2`

Generates one canonical Digest authorization header field value from a normalized `digest_authorization/1` term.

Compilation flags:
`static`
Template:
`generate_authorization(Authorization,HeaderValue)`
Mode and number of proofs:
`generate_authorization(+compound,-atom)` - `one_or_error`
Exceptions:
`Authorization` is not a valid normalized Digest authorization term:
`domain_error(http_digest_term(authorization),Authorization)`
`Authorization` is missing a required field:
`domain_error(http_digest_term(authorization),missing(Name))`
`Authorization` contains a duplicated field:
`domain_error(http_digest_term(authorization),duplicate(Name))`
`Authorization` contains an unexpected field:
`domain_error(http_digest_term(authorization),unexpected(Name))`
`Authorization` contains an invalid field:
`domain_error(http_digest_term(authorization),invalid(Name))`
`Authorization` fields are not in canonical order:
`domain_error(http_digest_term(authorization),invalid_order)`
`Authorization` contains inconsistent qop, nonce-count, and cnonce fields:
`domain_error(http_digest_term(authorization),inconsistent(qop_nonce_count_cnonce))`
`Authorization` contains an invalid algorithm:
`domain_error(http_digest_algorithm,Algorithm)`
`Authorization` contains an invalid qop value:
`domain_error(http_digest_qop,Qop)`

### `parse_authentication_info/2`

Parses one `Authentication-Info` header field value into a normalized `digest_authentication_info/1` term.

Compilation flags:
`static`
Template:
`parse_authentication_info(Text,AuthenticationInfo)`
Mode and number of proofs:
`parse_authentication_info(++text,-compound)` - `one_or_error`
Exceptions:
`Text` is neither a variable nor text:
`type_error(text,Text)`
`Text` is not a valid Digest `Authentication-Info` header value:
`domain_error(http_digest_header(authentication_info),invalid(syntax))`
`Text` contains a duplicated Digest authentication-info directive:
`domain_error(http_digest_header(authentication_info),duplicate(Name))`
`Text` contains an unexpected Digest authentication-info directive:
`domain_error(http_digest_header(authentication_info),unexpected(Name))`
`Text` contains an invalid Digest authentication-info directive value:
`domain_error(http_digest_header(authentication_info),invalid(Name))`

### `generate_authentication_info/2`

Generates one canonical `Authentication-Info` header field value from a normalized `digest_authentication_info/1` term.

Compilation flags:
`static`
Template:
`generate_authentication_info(AuthenticationInfo,HeaderValue)`
Mode and number of proofs:
`generate_authentication_info(+compound,-atom)` - `one_or_error`
Exceptions:
`AuthenticationInfo` is not a valid normalized Digest authentication-info term:
`domain_error(http_digest_term(authentication_info),AuthenticationInfo)`
`AuthenticationInfo` contains no field to generate:
`domain_error(http_digest_term(authentication_info),missing(all))`
`AuthenticationInfo` contains a duplicated field:
`domain_error(http_digest_term(authentication_info),duplicate(Name))`
`AuthenticationInfo` contains an unexpected field:
`domain_error(http_digest_term(authentication_info),unexpected(Name))`
`AuthenticationInfo` contains an invalid field:
`domain_error(http_digest_term(authentication_info),invalid(Name))`
`AuthenticationInfo` fields are not in canonical order:
`domain_error(http_digest_term(authentication_info),invalid_order)`
`AuthenticationInfo` contains inconsistent qop, nonce-count, and cnonce fields:
`domain_error(http_digest_term(authentication_info),inconsistent(qop_nonce_count_cnonce))`

### `authorize_request/6`

Decorates a normalized HTTP request with a Digest `Authorization` header computed from a normalized challenge term, username, password, and options.

Compilation flags:
`static`
Template:
`authorize_request(Request,Challenge,Username,Password,AuthorizedRequest,Options)`
Mode and number of proofs:
`authorize_request(+compound,+compound,++text,++text,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Request` is not a valid normalized HTTP request term:
`domain_error(http_request,Request)`
`Challenge` is not a valid normalized Digest challenge term:
`domain_error(http_digest_term(challenge),Challenge)`
`Username` or `Password` is neither a variable nor text:
`type_error(text,Text)`
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid Digest authorization option:
`domain_error(http_digest_authorize_request_option,Option)`
`Challenge` contains an unsupported algorithm:
`domain_error(http_digest_algorithm,Algorithm)`
`Challenge` contains an unsupported qop value:
`domain_error(http_digest_qop,Qop)`
`Challenge` contains an unsupported charset:
`domain_error(http_digest_charset,Charset)`
The authorized request violates normalized HTTP request semantics:
`domain_error(http_header_semantics,Header)`

### `protect_request/4`

Verifies a normalized HTTP request using a Digest verifier object and returns either `continue(Request)` or `respond(Response)`.

Compilation flags:
`static`
Template:
`protect_request(Request,Verifier,Action,Options)`
Mode and number of proofs:
`protect_request(+compound,+object_identifier,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Request` is not a valid normalized HTTP request term:
`domain_error(http_request,Request)`
`Verifier` is a variable:
`instantiation_error`
`Verifier` is neither a variable nor an existing object:
`existence_error(http_digest_verifier,Verifier)`
`Verifier` does not implement the Digest verifier protocol:
`domain_error(http_digest_verifier,Verifier)`
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid Digest protection option:
`domain_error(http_digest_protect_request_option,Option)`
`Options` is missing a required Digest protection option:
`domain_error(http_digest_protect_request_option,Option)`
`Options` contains an invalid Digest status:
`domain_error(http_digest_status,Status)`
`Options` contains an invalid Digest algorithm:
`domain_error(http_digest_algorithm,Algorithm)`
`Options` contains an invalid Digest qop value:
`domain_error(http_digest_qop,Qop)`
`Options` contains an invalid Digest charset:
`domain_error(http_digest_charset,Charset)`

### `unauthorized_response/3`

Builds a normalized `401 Unauthorized` response and returns the generated normalized Digest challenge term.

Compilation flags:
`static`
Template:
`unauthorized_response(Challenge,Response,Options)`
Mode and number of proofs:
`unauthorized_response(-compound,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid Digest unauthorized-response option:
`domain_error(http_digest_unauthorized_response_option,Option)`
`Options` is missing a required Digest unauthorized-response option:
`domain_error(http_digest_unauthorized_response_option,Option)`
`Options` contains an invalid Digest status:
`domain_error(http_digest_status,Status)`
`Options` contains an invalid Digest algorithm:
`domain_error(http_digest_algorithm,Algorithm)`
`Options` contains an invalid Digest qop value:
`domain_error(http_digest_qop,Qop)`
`Options` contains an invalid Digest charset:
`domain_error(http_digest_charset,Charset)`
The generated response violates normalized HTTP response semantics:
`domain_error(http_header_semantics,Header)`

### `unauthorized_response/4`

Decorates a normalized HTTP response with an explicit normalized Digest challenge term and returns the resulting `401 Unauthorized` response.

Compilation flags:
`static`
Template:
`unauthorized_response(Challenge,Response0,Response,Options)`
Mode and number of proofs:
`unauthorized_response(+compound,+compound,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Challenge` is not a valid normalized Digest challenge term:
`domain_error(http_digest_term(challenge),Challenge)`
`Response0` is not a valid normalized HTTP response term:
`domain_error(http_response,Response0)`
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid Digest unauthorized-response option:
`domain_error(http_digest_unauthorized_response_option,Option)`
`Challenge` contains an invalid Digest charset:
`domain_error(http_digest_charset,Charset)`
`Options` contains an invalid Digest status:
`domain_error(http_digest_status,Status)`
The decorated response violates normalized HTTP response semantics:
`domain_error(http_header_semantics,Header)`

### `add_authentication_info/4`

Decorates a normalized HTTP response with an `Authentication-Info` header computed from a previously verified request and options. The `nextnonce` option accepts `false` to omit the field, `true` to generate a fresh nonce using `nonce_secret/1`, or an explicit nonce atom to emit verbatim.

Compilation flags:
`static`
Template:
`add_authentication_info(Request,Response0,Response,Options)`
Mode and number of proofs:
`add_authentication_info(+compound,+compound,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Request` is not a valid normalized HTTP request term:
`domain_error(http_request,Request)`
`Request` is not annotated with a verified Digest property:
`domain_error(http_digest_verified_request,missing(Property))`
`Response0` is not a valid normalized HTTP response term:
`domain_error(http_response,Response0)`
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid authentication-info option:
`domain_error(http_digest_add_authentication_info_option,Option)`
`Options` is missing a required authentication-info option:
`domain_error(http_digest_add_authentication_info_option,Option)`
The decorated response violates normalized HTTP response semantics:
`domain_error(http_header_semantics,Header)`

## Protected predicates

(no local declarations; see entity ancestors if any)

## Private predicates

(no local declarations; see entity ancestors if any)

## Operators

(none)