On this page:
13.1 Integrity Checking
md-algorithm/  c
md-bytes-source/  c
well-formed-integrity-info/  c
13.2 Signature Checking
13.2.1 Signature Verification Model
13.2.2 Signature Check Bindings
siginfo-variant/  c
well-formed-signature-info/  c

13 Data Verification

When Xiden reproduces data from a source, that data may contain dangerous code. Since Xiden cannot detect motives, it concerns itself only with enforcing the user’s level of trust in the data. Data verification is addressed using an integrity check and a signature check under a runtime configuration. Each check is security critical.

13.1 Integrity Checking

 (require xiden/integrity) package: xiden


(struct integrity-info (algorithm digest))

  algorithm : md-algorithm/c
  digest : bytes?
Represents integrity information for bytes. Given bytes from some source, the bytes pass an integrity check if they, when applied to algorithm, produce a value equal? to digest.

A contract that accepts one of the symbols in md-algorithms.

A list of symbols that represent supported message digest algorithms.

Bound to

This contract matches a value V suitable for use in make-digest.

Given (path-string? V), the bytes are drawn from the file located at V. Given (bytes? V) or (input-port? V), the bytes are drawn directly from V.

A contract that recognizes instances of integrity-info, and verifies if the field values are logically consistent. It checks if the hash algorithm is valid, and if the digest is a byte string. It does not verify if the digest length is appropriate for the algorithm.


(check-integrity #:trust-bad-digest trust-bad-digest 
  trust-bad-digest : any/c
  intinfo : (or/c #f integrity-info?)
  variant : md-bytes-source/c
Performs an integrity check. See $integrity.

If trust-bad-digest is a true value, the integrity check passes unconditionally. Otherwise, the check passes if a message digest derived from variant is consistent with intinfo.

The check fails in all other conditions.


(struct $integrity $message (ok? stage info)
  ok? : boolean?
  stage : symbol?
  info : any/c
A message that reports the results of an integrity check.

ok? is #t if the check passed.

stage is a symbol that tells a maintainer which procedure created the given $integrity instance.

info is the Racket value presented as integrity information for the check.


(integrity algorithm digest)  well-formed-integrity-info/c

  algorithm : md-algorithm/c
  digest : bytes?
An abbreviated constructor for integrity-info that performs stronger validation on arguments.

Meant for use in package definitions when declaring package inputs.


(make-digest variant algorithm)  bytes?

  variant : md-bytes-source/c
  algorithm : md-algorithm/c
Returns the raw byte content of algorithm applied to bytes from variant.


(bind-trust-list trusted)  (-> path-string? boolean?)

  trusted : (listof well-formed-integrity-info/c)
Returns a procedure P, such that (P "/path/to/file") (for example) is #t if the given file passes an integrity check for one of the integrity-info structures in trusted.

13.2 Signature Checking

 (require xiden/signature) package: xiden

xiden/signature authenticates data providers through their digital signatures.

13.2.1 Signature Verification Model

Xiden’s signature checking process is equivalent to the following OpenSSL command:

$ openssl pkeyutl -verify -sigfile SIGFILE -pubin -inkey PUBKEY <DIGEST

Specifically, it reads unencoded bytes for a message digest (a.k.a. content hash) and verifies a signature from a signature file (SIGFILE) and a public key file (PUBKEY).

This implies that Xiden accepts any format OpenSSL does for the signature and public key, but the cipher algorithm used to create the signature must support the message digest algorithm used to create the digest.

If you create a signature and cannot seem to pass the signature check, make sure that you are actually signing the raw bytes for a message digest because that’s what Xiden checks against. If you use a command like openssl dgst -sign ..., then you would be signing an ANS.1-encoded digest. Use openssl pkeyutl -binary ... instead.

13.2.2 Signature Check Bindings

In the context of signature checking, a public key or signature can be expressed using a variant value type.

A byte string is used as-is for verfication. This allows you to pass a public key or signature as raw bytes directly into a signature check.

(signature-info #"-----BEGIN PUBLIC KEY-----\nMIIBIjAN..." #"*&\2...")

A Racket string is instead treated as a source, so that the bytes can be fetched from elsewhere.

(signature-info "https://example.com/public.pem" (from-file "local.sign"))


(struct signature-info (pubkey body))

  pubkey : siginfo-variant/c
  body : siginfo-variant/c
Holds an expression of a public key file and the bytes of a signature created using a private key.


(signature pubkey body)  signature-info?

  pubkey : siginfo-variant/c
  body : siginfo-variant/c
An abbreviated signature-info constructor for use in package definitions.

Recognizes an instance of signature-info that is suitable for use in signature checking.


(get-public-key-path variant)  path?

  variant : (or/c string? bytes?)
Returns a workspace-relative path to a public key file. The file may be cached.


(check-signature #:trust-public-key? trust-public-key? 
  #:public-key-path public-key-path 
  #:trust-unsigned trust-unsigned 
  #:trust-bad-digest trust-bad-digest 
  trust-public-key? : (-> path-string? any/c)
  public-key-path : path-string?
  trust-unsigned : any/c
  trust-bad-digest : any/c
  siginfo : (or/c #f signature-info?)
  intinfo : well-formed-integrity-info/c
This procedure returns the result of a signature check, which follows the high-level rules shown below. Each rule is processed in the order shown.

If trust-bad-digest is true, then the check passes regardless of the value set for any other argument. This is because if any data are trusted, then the same applies to any signature.

If trust-unsigned is true and (well-formed-signature-info/c siginfo) is #f, then the check passes. This is because a failure to declare a signature is the same as not providing a signature. Trusting unsigned input means being okay with this.

If (trust-public-key? public-key-path) is true, both siginfo and intinfo are well-formed, and the public key verifies the signature against the integrity information, the check passes.

The check fails in all other conditions.


(struct $signature $message (ok? stage public-key-path)
  ok? : boolean?
  stage : symbol?
  public-key-path : (or/c #f path-string?)
A message that reports the results of a signature check.

ok? is #t if the check passed.

stage is a symbol representing the procedure responsible for the check result.

public-key-path is a path to a cached public key file used for a check, or #f if a public key is not relevant.