Engine/TrustRating

p≡p Trust Rating Engine

Front matter

Title: Trust Rating Specification
Author: Volker Birk
Team: Engine Team
Reviewer(s): TBD
Created: 2021-02-11
Last updated: 2021-02-11
Ticket reference: ENGINE-847

Introduction

p≡p is securing electronic communication. It is starting with Zero Trust, then building Trust following the Trust On First Use pattern, eventually completed by manual Trust Checks or integration in external Identity Management solutions. Trust Rating is based on this status information. Additionally, it considers the quality of the used cryptography.

Goals

This document describes the p≡p Trust Rating Engine, which is part of the p≡p engine, as well as the API for application programmers, which is part of the p≡p API.

Ratings are calculated for Outgoing Messages and Communication Channels on the one hand, and for Incoming Messages on the other.

The delivered rating is the base for the UI concept of p≡p.

Glossary

  • User: a human being using a p≡p installation in Person to Person Communication

  • System: an IT system being secured by a p≡p installation in Machine to Machine Communication.

  • Identity: maps a Network Address to a User or System (“the Network Address, under which a User or a System appears in the network”)

Background

The Trust Rating Engine is a core part of the p≡p engine. It is an innovation of p≡p.

Abstract

The p≡p Trust Rating Engine delivers two types of Ratings:

  1. Ratings for “What would be the dependability of Privacy and Security when we send out a message now?”

  2. Ratings for “A message reached us, were Privacy and Security guaranteed for all what we know?”

It bases on the rating of

  • Cryptographic properties
  • Keys
  • Trust information and
  • Attack detection

by combining these information for each rating.

A p≡p Trust Rating is calulated in a three/four step process:

  1. Determine communication type (comm_type), a status sequence of cryptographic properties and key information

  2. Caluclate the rating values of different sources

  3. Add the rating values together

  4. Optional: calculate a color value as brief summary of the Rating

Use cases

This specification defines the design of the Managed Group Encryption Protocol. The following use cases illustrate the reasons why this design was chosen.

Use case:

Sample:

Use case:

Sample:

Technical Requirements

Key Rating

Default Key and Sender Key

Trust managment in management.db

Trust on First Use

Trustwords check

Attack detection

Solution

Status quo

Definitions

comm_type

The comm_type is an 8 bit integer for the rating base defined as sequence of possible states of keys and cryptography for an encrypted communication in the lower 7 bits. When all bits are 0 then the comm_type is unknown (no value). Bit 7 adds trust status information; if it is set then a reliable trust check (i.e. manually executed) was successful.

The following comm_type values are used:

PEP_ct_unknown = 0,

// range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable

PEP_ct_no_encryption = 0x01,                // generic
PEP_ct_no_encrypted_channel = 0x02,
PEP_ct_key_not_found = 0x03,
PEP_ct_key_expired = 0x04,
PEP_ct_key_revoked = 0x05,
PEP_ct_key_b0rken = 0x06,
PEP_ct_key_expired_but_confirmed = 0x07, // NOT with confirmed bit. Just retaining info here in case of renewal.
PEP_ct_my_key_not_included = 0x09,

PEP_ct_security_by_obscurity = 0x0a,
PEP_ct_b0rken_crypto = 0x0b,
PEP_ct_key_too_short = 0x0c,

PEP_ct_compromised = 0x0e,                  // known compromised connection
PEP_ct_compromized = 0x0e,                  // deprecated misspelling
PEP_ct_mistrusted = 0x0f,                   // known mistrusted key

// range 0x10 to 0x3f: unconfirmed encryption

PEP_ct_unconfirmed_encryption = 0x10,       // generic
PEP_ct_OpenPGP_weak_unconfirmed = 0x11,     // RSA 1024 is weak

PEP_ct_to_be_checked = 0x20,                // generic
PEP_ct_SMIME_unconfirmed = 0x21,
PEP_ct_CMS_unconfirmed = 0x22,

PEP_ct_strong_but_unconfirmed = 0x30,       // generic
PEP_ct_OpenPGP_unconfirmed = 0x38,          // key at least 2048 bit RSA or EC
PEP_ct_OTR_unconfirmed = 0x3a,

// range 0x40 to 0x7f: unconfirmed encryption and anonymization

PEP_ct_unconfirmed_enc_anon = 0x40,         // generic
PEP_ct_pEp_unconfirmed = 0x7f,

PEP_ct_confirmed = 0x80,                    // this bit decides if trust is confirmed

// range 0x81 to 0x8f: reserved
// range 0x90 to 0xbf: confirmed encryption

PEP_ct_confirmed_encryption = 0x90,         // generic
PEP_ct_OpenPGP_weak = 0x91,                 // RSA 1024 is weak (unused)

PEP_ct_to_be_checked_confirmed = 0xa0,      // generic
PEP_ct_SMIME = 0xa1,
PEP_ct_CMS = 0xa2,

PEP_ct_strong_encryption = 0xb0,            // generic
PEP_ct_OpenPGP = 0xb8,                      // key at least 2048 bit RSA or EC
PEP_ct_OTR = 0xba,

// range 0xc0 to 0xff: confirmed encryption and anonymization

PEP_ct_confirmed_enc_anon = 0xc0,           // generic
PEP_ct_pEp = 0xff

Rating values

The Rating values are the result of a Rating calculation. The following Rating values are defined:

PEP_rating_undefined = 0,

// no color

PEP_rating_cannot_decrypt = 1,
PEP_rating_have_no_key = 2,
PEP_rating_unencrypted = 3,
PEP_rating_unreliable = 5,

PEP_rating_b0rken = -2,

// yellow

PEP_rating_reliable = 6,

// green

PEP_rating_trusted = 7,
PEP_rating_trusted_and_anonymized = 8,
PEP_rating_fully_anonymous = 9, 

// red

PEP_rating_mistrust = -1,
PEP_rating_under_attack = -3

Base Rating

The Base Rating Rʙ is a Rating value calculated by mapping a comm_type c with the Rating map function:

Rʙ := rating_from_comm_type( c )

DYNAMIC_API PEP_rating rating_from_comm_type(PEP_comm_type ct)
{
    if (ct == PEP_ct_unknown)
        return PEP_rating_undefined;

    else if (ct == PEP_ct_key_not_found)
        return PEP_rating_have_no_key;

    else if (ct == PEP_ct_compromised)
        return PEP_rating_under_attack;

    else if (ct == PEP_ct_mistrusted)
        return PEP_rating_mistrust;

    if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel ||
            ct == PEP_ct_my_key_not_included)
            return PEP_rating_unencrypted;

    if (ct >= PEP_ct_confirmed_enc_anon)
        return PEP_rating_trusted_and_anonymized;

    else if (ct >= PEP_ct_strong_encryption)
        return PEP_rating_trusted;

    else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
        return PEP_rating_reliable;

    else
        return PEP_rating_unreliable;
}

Addition of Rating values

Two Rating values can be added together. The result is a Rating value.

R = R₁ ⊕ R₂

The sum of two Rating values is undefined if at least one of the summands is undefined. Otherwise the sum is the minimum of the two summands.

DYNAMIC_API PEP_rating add_rating(PEP_rating rating1, PEP_rating rating2)
{
    if (rating1 == PEP_rating_undefined || rating2 == PEP_rating_undefined)
        return PEP_rating_undefined;

    return rating1 > rating2 ? rating2 : rating1;
}

This addition is commutative and associative:

  1. Commutative: R₁ ⊕ R₂ = R₂ ⊕ R₁
  2. Associative: (R₁ ⊕ R₂) ⊕ R₃ = R₁ ⊕ (R₂ ⊕ R₃)

Hence multiple Rating additions can be executed without caring about sequence.

Design

Overview

Dependencies

Security considerations

Pros and Cons

API

For the API see in branch ENGINE-847 pEpEngine/src/rating_api.h

/**
 * @file    rating_api.h
 * @brief   rating functions
 * @license GNU General Public License 3.0 - see LICENSE.txt
 */

#ifndef RATING_API_H
#define RATING_API_H


#include "message.h"
#include "stringpair.h"


#ifdef __cplusplus
extern "C" {
#endif


/**
 *  @enum    PEP_rating
 *
 *  @brief    TODO
 *
 */
typedef enum _PEP_rating {
    PEP_rating_undefined = 0,

    // no color

    PEP_rating_cannot_decrypt = 1,
    PEP_rating_have_no_key = 2,
    PEP_rating_unencrypted = 3,
    PEP_rating_unreliable = 5,

    PEP_rating_b0rken = -2,

    // yellow

    PEP_rating_reliable = 6,

    // green

    PEP_rating_trusted = 7,
    PEP_rating_trusted_and_anonymized = 8,
    PEP_rating_fully_anonymous = 9, 

    // red

    PEP_rating_mistrust = -1,
    PEP_rating_under_attack = -3
} PEP_rating;


/**
 *  <!--       rating_from_comm_type()       -->
 *
 *  @brief Get the rating for a comm type
 *
 *  @param[in]   ct    the comm type to deliver the rating for
 *
 *  @retval PEP_rating    rating value for comm type ct
 *
 *
 */

DYNAMIC_API PEP_rating rating_from_comm_type(PEP_comm_type ct);


/**
 *  <!--       add_rating()       -->
 *
 *  @brief add two ratings together
 *
 *  @param[in]   rating1    rating to add to
 *  @param[in]   rating2    rating added
 *
 *  @retval PEP_rating    rating value for rating1 + rating2
 *
 *
 */

DYNAMIC_API PEP_rating add_rating(PEP_rating rating1, PEP_rating rating2);


typedef PEP_STATUS (*channel_rating_t)(
        PEP_SESSION session, pEp_identity *ident, PEP_rating *rating);

/**
 *  <!--       rating_of_new_channel()       -->
 *
 *  @brief get the rating for a new channel to a communication partner
 *         outgoing messages are rated using this
 *
 *  @param[in]      session     session handle
 *  @param[in,out]  ident       identity to calculate the rating for
 *  @param[out]     rating      calculated rating
 *
 *  @retval error status or PEP_STATUS_OK on success
 *
 *  @warning this function calls update_identity() on the stored identity
*/

DYNAMIC_API PEP_STATUS rating_of_new_channel(
            PEP_SESSION session,
            pEp_identity *ident,
            PEP_rating *rating
        );


/**
 *  <!--       last_rating_of_new_channel()       -->
 *
 *  @brief get the rating of a channel to a communication partner based on last
 *         calculated comm_type
 *         this is for fast outgoing message preview ratings
 *
 *  @param[in]      session     session handle
 *  @param[in,out]  ident       identity to calculate the rating for
 *  @param[out]     rating      calculated rating
 *
 *  @retval error status or PEP_STATUS_OK on success
 *
 *  @warning this function uses a given .comm_type
 *           this function calls get_identity() if .comm_type is not given
 *           .address and .user_id must be given for a stored contact
 *           .address must be given if the identity is not from a stored contact
*/

DYNAMIC_API PEP_STATUS last_rating_of_new_channel(
            PEP_SESSION session,
            pEp_identity *ident,
            PEP_rating *rating
        );


/**
 *  <!--       rating_of_existing_channel()       -->
 *
 *  @brief get the rating for an existing channel to a communication partner
 *         incoming messages are rated using this
 *
 *  @param[in]      session     session handle
 *  @param[in]      ident       identity to calculate the rating for
 *  @param[out]     rating      calculated rating
 *
 *  @retval error status or PEP_STATUS_OK on success
 *
 *  @warning this function does not call update_identity() and expects .fpr
 *           being preset to comm_partner's key used in this channel
 *           .address and .user_id must be given for a stored contact
 *           .address must be given if the identity is not from a stored contact
*/

DYNAMIC_API PEP_STATUS rating_of_existing_channel(
            PEP_SESSION session,
            pEp_identity *ident,
            PEP_rating *rating
        );


/**
 *  <!--       outgoing_message_rating()       -->
 *
 *  @brief Get rating for an outgoing message
 *
 *  @param[in]   session    session handle
 *  @param[in]   msg        message to get the rating for
 *  @param[out]  rating     rating for the message
 *
 *  @retval error status or PEP_STATUS_OK on success
 *
 *  @warning msg->from must point to a valid pEp_identity
 *           msg->dir must be PEP_dir_outgoing
 *           the ownership of msg remains with the caller
 *
 */

DYNAMIC_API PEP_STATUS outgoing_message_rating(
        PEP_SESSION session,
        message *msg,
        PEP_rating *rating
    );


/**
 *  <!--       outgoing_message_rating_preview()       -->
 *
 *  @brief Get rating preview
 *
 *  @param[in]   session    session handle
 *  @param[in]   msg        message to get the rating for
 *  @param[out]  rating     rating preview for the message
 *
 *  @retval error status or PEP_STATUS_OK on success
 *
 *  @warning msg->from must point to a valid pEp_identity
 *           msg->dir must be PEP_dir_outgoing
 *           the ownership of msg remains with the caller
 *
 */

DYNAMIC_API PEP_STATUS outgoing_message_rating_preview(
        PEP_SESSION session,
        message *msg,
        PEP_rating *rating
    );


/** @internal
 *
 *  <!--       decrypt_rating()       -->
*/

PEP_rating decrypt_rating(PEP_STATUS status);


/**
 *  <!--       incoming_message_rating()       -->
 *
 *  @brief Get rating of an incoming message
 *
 *  @param[in]   session            session handle
 *  @param[in]   src                encrypted version of message to get the rating for
 *  @param[in]   dst                decrypted version of message to get the rating for
 *  @param[in]   known_keys         list of fprs of keys known to be used to encrypt src
 *  @param[in]   extra_keys         extra keys declared by the sender
 *  @param[in]   decrypt_status     return value of decrypt_and_verify()
 *  @param[out]  rating             rating for the message
 *
 *  @retval error status or PEP_STATUS_OK on success
 *
 *  @warning src->from must point to a valid pEp_identity
 *           src->dir must be PEP_dir_incoming
 *           src->enc_format must be set to the actual encryption format
 *           dst->_sender_fpr must be set if available
 *           dst->to->fpr and dst->cc->fpr should be set to the keys used for
 *           recipients, respectively
 *           extra_keys are pairs (name, fpr)
 *           decrypt_status must be PEP_VERFIY_DIFFERENT_KEYS in case of a
 *           partitioned format and there is no guarantee that the sender key
 *           was being used to sign all partitions
 *
 */

DYNAMIC_API PEP_STATUS incoming_message_rating(
        PEP_SESSION session,
        const message *src,
        const message *dst,
        const stringlist_t *known_keys,
        const stringpair_list_t *extra_keys,
        PEP_STATUS decrypt_status,
        PEP_rating *rating
    );


#ifdef __cplusplus
}
#endif

#endif // RATING_API_H

Actions

Rating a newly created message

Rating

Storage in management DB

The following information must be stored:

Implementation

Security considerations

Service requirements

Service tooling

Logging

Enterprise Toolkit

Affected Teams

  • Implementation: Engine team

Additionally:

  • All p≡p for E-Mail Application teams for implementing UI
  • All p≡p Adapter developers for implementing the extension to the p≡p API
  • The p≡p Enterprise Toolkit developers
  • The p≡p Service & QA team

See also