merged in sync ENGINE-551
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 07 Aug 2019 11:55:15 +0200
branchENGINE-551
changeset 3949571afb5abe5f
parent 3914 eec042946bec
parent 3941 1f8cf96379ac
child 3950 7ee96089a3ff
merged in sync
src/message_api.c
test/src/SuiteMaker.cc
     1.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Tue Jul 09 11:24:18 2019 +0200
     1.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Wed Aug 07 11:55:15 2019 +0200
     1.3 @@ -1128,6 +1128,7 @@
     1.4  				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
     1.5  				COPY_PHASE_STRIP = NO;
     1.6  				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
     1.7 +				ENABLE_BITCODE = NO;
     1.8  				ENABLE_STRICT_OBJC_MSGSEND = YES;
     1.9  				ENABLE_TESTABILITY = YES;
    1.10  				GCC_C_LANGUAGE_STANDARD = gnu99;
    1.11 @@ -1189,11 +1190,15 @@
    1.12  				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
    1.13  				COPY_PHASE_STRIP = NO;
    1.14  				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
    1.15 +				ENABLE_BITCODE = NO;
    1.16  				ENABLE_NS_ASSERTIONS = NO;
    1.17  				ENABLE_STRICT_OBJC_MSGSEND = YES;
    1.18  				GCC_C_LANGUAGE_STANDARD = gnu99;
    1.19  				GCC_NO_COMMON_BLOCKS = YES;
    1.20 -				GCC_PREPROCESSOR_DEFINITIONS = "USE_SEQUOIA=1";
    1.21 +				GCC_PREPROCESSOR_DEFINITIONS = (
    1.22 +					"USE_SEQUOIA=1",
    1.23 +					NDEBUG,
    1.24 +				);
    1.25  				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
    1.26  				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
    1.27  				GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
     2.1 --- a/src/keymanagement.c	Tue Jul 09 11:24:18 2019 +0200
     2.2 +++ b/src/keymanagement.c	Wed Aug 07 11:55:15 2019 +0200
     2.3 @@ -249,7 +249,7 @@
     2.4          case PEP_ct_key_revoked:
     2.5          case PEP_ct_key_b0rken:
     2.6              // delete key from being default key for all users/identities
     2.7 -            status = remove_fpr_as_default(session, fpr); //BUFF: considers the key as "revoked" ...
     2.8 +            status = remove_fpr_as_default(session, fpr);
     2.9              status = update_trust_for_fpr(session, 
    2.10                                            fpr, 
    2.11                                            ct);
    2.12 @@ -257,7 +257,7 @@
    2.13              free(ident->fpr);
    2.14              ident->fpr = NULL;
    2.15              ident->comm_type = ct;            
    2.16 -            status = PEP_KEY_UNSUITABLE; //BUFF: ... and returns PEP_KEY_UNSUITABLE
    2.17 +            status = PEP_KEY_UNSUITABLE;
    2.18          default:
    2.19              break;
    2.20      }            
     3.1 --- a/src/message_api.c	Tue Jul 09 11:24:18 2019 +0200
     3.2 +++ b/src/message_api.c	Wed Aug 07 11:55:15 2019 +0200
     3.3 @@ -2570,8 +2570,8 @@
     3.4      
     3.5      if ((!slong || slong[0] == '\0')
     3.6           && (!sform || sform[0] == '\0')) {
     3.7 -        if (satt) {
     3.8 -            const char* inner_mime_type = satt->mime_type;
     3.9 +        const char* inner_mime_type = (satt ? satt->mime_type : NULL);     
    3.10 +        if (inner_mime_type) {
    3.11              if (strcasecmp(inner_mime_type, "text/plain") == 0) {
    3.12                  free(slong); /* in case of "" */
    3.13                  src->longmsg = strndup(satt->value, satt->size); 
     4.1 --- a/src/pgp_sequoia.c	Tue Jul 09 11:24:18 2019 +0200
     4.2 +++ b/src/pgp_sequoia.c	Wed Aug 07 11:55:15 2019 +0200
     4.3 @@ -2393,6 +2393,245 @@
     4.4      return PEP_UNKNOWN_ERROR;
     4.5  }
     4.6  
     4.7 +
     4.8 +PEP_STATUS pgp_renew_key(
     4.9 +    PEP_SESSION session, const char *fpr, const timestamp *ts)
    4.10 +{
    4.11 +    PEP_STATUS status = PEP_STATUS_OK;
    4.12 +    pgp_error_t err = NULL;
    4.13 +    pgp_tpk_t tpk = NULL;
    4.14 +    pgp_tpk_key_iter_t iter = NULL;
    4.15 +    pgp_key_pair_t keypair = NULL;
    4.16 +    pgp_signer_t signer = NULL;
    4.17 +    time_t t = mktime((struct tm *) ts);
    4.18 +
    4.19 +    T("(%s)", fpr);
    4.20 +
    4.21 +    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
    4.22 +    ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
    4.23 +
    4.24 +    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
    4.25 +    if (creation_time > t)
    4.26 +        // The creation time is after the expiration time!
    4.27 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
    4.28 +                  "creation time can't be after expiration time");
    4.29 +
    4.30 +    uint32_t delta = t - creation_time;
    4.31 +
    4.32 +
    4.33 +    iter = pgp_tpk_key_iter_valid(tpk);
    4.34 +    pgp_tpk_key_iter_certification_capable (iter);
    4.35 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
    4.36 +
    4.37 +    // If there are multiple certification capable subkeys, we just
    4.38 +    // take the first one, whichever one that happens to be.
    4.39 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
    4.40 +    if (! key)
    4.41 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
    4.42 +                   "%s has no usable certification capable key", fpr);
    4.43 +
    4.44 +    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
    4.45 +    if (! keypair)
    4.46 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
    4.47 +
    4.48 +    signer = pgp_key_pair_as_signer (keypair);
    4.49 +    if (! signer)
    4.50 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
    4.51 +
    4.52 +    tpk = pgp_tpk_set_expiry(&err, tpk, signer, delta);
    4.53 +    if (! tpk)
    4.54 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
    4.55 +
    4.56 +    status = tpk_save(session, tpk, NULL);
    4.57 +    tpk = NULL;
    4.58 +    ERROR_OUT(NULL, status, "Saving %s", fpr);
    4.59 +
    4.60 + out:
    4.61 +    pgp_signer_free (signer);
    4.62 +    pgp_key_pair_free (keypair);
    4.63 +    pgp_tpk_key_iter_free (iter);
    4.64 +    pgp_tpk_free(tpk);
    4.65 +
    4.66 +    T("(%s) -> %s", fpr, pEp_status_to_string(status));
    4.67 +    return status;
    4.68 +}
    4.69 +
    4.70 +PEP_STATUS pgp_revoke_key(
    4.71 +    PEP_SESSION session, const char *fpr, const char *reason)
    4.72 +{
    4.73 +    PEP_STATUS status = PEP_STATUS_OK;
    4.74 +    pgp_error_t err = NULL;
    4.75 +    pgp_tpk_t tpk = NULL;
    4.76 +    pgp_tpk_key_iter_t iter = NULL;
    4.77 +    pgp_key_pair_t keypair = NULL;
    4.78 +    pgp_signer_t signer = NULL;
    4.79 +
    4.80 +    T("(%s)", fpr);
    4.81 +
    4.82 +    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
    4.83 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
    4.84 +
    4.85 +    iter = pgp_tpk_key_iter_valid(tpk);
    4.86 +    pgp_tpk_key_iter_certification_capable (iter);
    4.87 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
    4.88 +
    4.89 +    // If there are multiple certification capable subkeys, we just
    4.90 +    // take the first one, whichever one that happens to be.
    4.91 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
    4.92 +    if (! key)
    4.93 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
    4.94 +                   "%s has no usable certification capable key", fpr);
    4.95 +
    4.96 +    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
    4.97 +    if (! keypair)
    4.98 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
    4.99 +
   4.100 +    signer = pgp_key_pair_as_signer (keypair);
   4.101 +    if (! signer)
   4.102 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
   4.103 +
   4.104 +    tpk = pgp_tpk_revoke_in_place(&err, tpk, signer,
   4.105 +                                  PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
   4.106 +                                  reason);
   4.107 +    if (! tpk)
   4.108 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   4.109 +
   4.110 +    assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
   4.111 +           == PGP_REVOCATION_STATUS_REVOKED);
   4.112 +
   4.113 +    status = tpk_save(session, tpk, NULL);
   4.114 +    tpk = NULL;
   4.115 +    ERROR_OUT(NULL, status, "Saving %s", fpr);
   4.116 +
   4.117 + out:
   4.118 +    pgp_signer_free (signer);
   4.119 +    pgp_key_pair_free (keypair);
   4.120 +    pgp_tpk_key_iter_free (iter);
   4.121 +    pgp_tpk_free(tpk);
   4.122 +
   4.123 +    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   4.124 +    return status;
   4.125 +}
   4.126 +
   4.127 +static void _pgp_key_expired(pgp_tpk_t tpk, const time_t when, bool* expired)
   4.128 +{
   4.129 +    // Is the TPK live?
   4.130 +    *expired = !pgp_tpk_alive_at(tpk, when);
   4.131 +
   4.132 +#ifdef TRACING
   4.133 +    {
   4.134 +        char buffer[26];
   4.135 +        time_t now = time(NULL);
   4.136 +
   4.137 +        if (when == now || when == now - 1) {
   4.138 +            sprintf(buffer, "now");
   4.139 +        } else {
   4.140 +            struct tm tm;
   4.141 +            gmtime_r(&when, &tm);
   4.142 +            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
   4.143 +        }
   4.144 +
   4.145 +        T("TPK is %slive as of %s", *expired ? "not " : "", buffer);
   4.146 +    }
   4.147 +#endif
   4.148 +    if (*expired)
   4.149 +        goto out;
   4.150 +
   4.151 +    // Are there at least one certification subkey, one signing subkey
   4.152 +    // and one encryption subkey that are live?
   4.153 +    //    int can_certify = 0, can_encrypt = 0, can_sign = 0;
   4.154 +    int can_encrypt = 0, can_sign = 0;
   4.155 +
   4.156 +    pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
   4.157 +    pgp_key_t key;
   4.158 +    pgp_signature_t sig;
   4.159 +    pgp_revocation_status_t rev;
   4.160 +    while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
   4.161 +        if (! sig)
   4.162 +            continue;
   4.163 +
   4.164 +        if (pgp_signature_can_encrypt_for_transport(sig)
   4.165 +            || pgp_signature_can_encrypt_at_rest(sig))
   4.166 +            can_encrypt = 1;
   4.167 +        if (pgp_signature_can_sign(sig))
   4.168 +            can_sign = 1;
   4.169 +        // if (pgp_signature_can_certify(sig))
   4.170 +        //     can_certify = 1;
   4.171 +
   4.172 +//        if (can_encrypt && can_sign && can_certify)
   4.173 +        if (can_encrypt && can_sign)
   4.174 +            break;
   4.175 +    }
   4.176 +    pgp_tpk_key_iter_free(key_iter);
   4.177 +
   4.178 +//    *expired = !(can_encrypt && can_sign && can_certify);
   4.179 +    *expired = !(can_encrypt && can_sign);
   4.180 +
   4.181 +    T("Key can%s encrypt, can%s sign, can%s certify => %sexpired",
   4.182 +      can_encrypt ? "" : "not",
   4.183 +      can_sign ? "" : "not",
   4.184 +      // can_certify ? "" : "not",
   4.185 +      *expired ? "" : "not ");
   4.186 +      
   4.187 +out:
   4.188 +    // Er, this might be problematic in terms of internal vs. external in log. FIXME?
   4.189 +    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   4.190 +    return;
   4.191 +}
   4.192 +                            
   4.193 +PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
   4.194 +                           const time_t when, bool *expired)
   4.195 +{
   4.196 +    PEP_STATUS status = PEP_STATUS_OK;
   4.197 +    pgp_tpk_t tpk = NULL;
   4.198 +    T("(%s)", fpr);
   4.199 +
   4.200 +    assert(session);
   4.201 +    assert(fpr);
   4.202 +    assert(expired);
   4.203 +
   4.204 +    *expired = false;
   4.205 +
   4.206 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   4.207 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   4.208 +    pgp_fingerprint_free(pgp_fpr);
   4.209 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   4.210 +
   4.211 +    _pgp_key_expired(tpk, when, expired);
   4.212 + out:
   4.213 +    pgp_tpk_free(tpk);
   4.214 +    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   4.215 +    return status;
   4.216 +}
   4.217 +
   4.218 +PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
   4.219 +{
   4.220 +    PEP_STATUS status = PEP_STATUS_OK;
   4.221 +    pgp_tpk_t tpk;
   4.222 +
   4.223 +    T("(%s)", fpr);
   4.224 +
   4.225 +    assert(session);
   4.226 +    assert(fpr);
   4.227 +    assert(revoked);
   4.228 +
   4.229 +    *revoked = false;
   4.230 +
   4.231 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   4.232 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   4.233 +    pgp_fingerprint_free(pgp_fpr);
   4.234 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   4.235 +
   4.236 +    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   4.237 +    *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
   4.238 +    pgp_revocation_status_free (rs);
   4.239 +    pgp_tpk_free(tpk);
   4.240 +
   4.241 + out:
   4.242 +    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   4.243 +    return status;
   4.244 +}
   4.245 +
   4.246  PEP_STATUS pgp_get_key_rating(
   4.247      PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
   4.248  {
   4.249 @@ -2412,10 +2651,20 @@
   4.250  
   4.251      *comm_type = PEP_ct_OpenPGP_unconfirmed;
   4.252  
   4.253 -    if (pgp_tpk_expired(tpk)) {
   4.254 +    bool expired = false;
   4.255 +    
   4.256 +    // MUST guarantee the same behaviour.
   4.257 +    _pgp_key_expired(tpk, time(NULL), &expired);
   4.258 +    
   4.259 +    if (expired) {
   4.260          *comm_type = PEP_ct_key_expired;
   4.261 -        goto out;
   4.262 +        goto out;        
   4.263      }
   4.264 +    
   4.265 +    // if (pgp_tpk_expired(tpk)) {
   4.266 +    //     *comm_type = PEP_ct_key_expired;
   4.267 +    //     goto out;
   4.268 +    // }
   4.269  
   4.270      pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   4.271      pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
   4.272 @@ -2478,231 +2727,6 @@
   4.273  }
   4.274  
   4.275  
   4.276 -PEP_STATUS pgp_renew_key(
   4.277 -    PEP_SESSION session, const char *fpr, const timestamp *ts)
   4.278 -{
   4.279 -    PEP_STATUS status = PEP_STATUS_OK;
   4.280 -    pgp_error_t err = NULL;
   4.281 -    pgp_tpk_t tpk = NULL;
   4.282 -    pgp_tpk_key_iter_t iter = NULL;
   4.283 -    pgp_key_pair_t keypair = NULL;
   4.284 -    pgp_signer_t signer = NULL;
   4.285 -    time_t t = mktime((struct tm *) ts);
   4.286 -
   4.287 -    T("(%s)", fpr);
   4.288 -
   4.289 -    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
   4.290 -    ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
   4.291 -
   4.292 -    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
   4.293 -    if (creation_time > t)
   4.294 -        // The creation time is after the expiration time!
   4.295 -        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   4.296 -                  "creation time can't be after expiration time");
   4.297 -
   4.298 -    uint32_t delta = t - creation_time;
   4.299 -
   4.300 -
   4.301 -    iter = pgp_tpk_key_iter_valid(tpk);
   4.302 -    pgp_tpk_key_iter_certification_capable (iter);
   4.303 -    pgp_tpk_key_iter_unencrypted_secret (iter, true);
   4.304 -
   4.305 -    // If there are multiple certification capable subkeys, we just
   4.306 -    // take the first one, whichever one that happens to be.
   4.307 -    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
   4.308 -    if (! key)
   4.309 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   4.310 -                   "%s has no usable certification capable key", fpr);
   4.311 -
   4.312 -    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   4.313 -    if (! keypair)
   4.314 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
   4.315 -
   4.316 -    signer = pgp_key_pair_as_signer (keypair);
   4.317 -    if (! signer)
   4.318 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
   4.319 -
   4.320 -    tpk = pgp_tpk_set_expiry(&err, tpk, signer, delta);
   4.321 -    if (! tpk)
   4.322 -        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   4.323 -
   4.324 -    status = tpk_save(session, tpk, NULL);
   4.325 -    tpk = NULL;
   4.326 -    ERROR_OUT(NULL, status, "Saving %s", fpr);
   4.327 -
   4.328 - out:
   4.329 -    pgp_signer_free (signer);
   4.330 -    pgp_key_pair_free (keypair);
   4.331 -    pgp_tpk_key_iter_free (iter);
   4.332 -    pgp_tpk_free(tpk);
   4.333 -
   4.334 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   4.335 -    return status;
   4.336 -}
   4.337 -
   4.338 -PEP_STATUS pgp_revoke_key(
   4.339 -    PEP_SESSION session, const char *fpr, const char *reason)
   4.340 -{
   4.341 -    PEP_STATUS status = PEP_STATUS_OK;
   4.342 -    pgp_error_t err = NULL;
   4.343 -    pgp_tpk_t tpk = NULL;
   4.344 -    pgp_tpk_key_iter_t iter = NULL;
   4.345 -    pgp_key_pair_t keypair = NULL;
   4.346 -    pgp_signer_t signer = NULL;
   4.347 -
   4.348 -    T("(%s)", fpr);
   4.349 -
   4.350 -    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
   4.351 -    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   4.352 -
   4.353 -    iter = pgp_tpk_key_iter_valid(tpk);
   4.354 -    pgp_tpk_key_iter_certification_capable (iter);
   4.355 -    pgp_tpk_key_iter_unencrypted_secret (iter, true);
   4.356 -
   4.357 -    // If there are multiple certification capable subkeys, we just
   4.358 -    // take the first one, whichever one that happens to be.
   4.359 -    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
   4.360 -    if (! key)
   4.361 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   4.362 -                   "%s has no usable certification capable key", fpr);
   4.363 -
   4.364 -    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   4.365 -    if (! keypair)
   4.366 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
   4.367 -
   4.368 -    signer = pgp_key_pair_as_signer (keypair);
   4.369 -    if (! signer)
   4.370 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
   4.371 -
   4.372 -    tpk = pgp_tpk_revoke_in_place(&err, tpk, signer,
   4.373 -                                  PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
   4.374 -                                  reason);
   4.375 -    if (! tpk)
   4.376 -        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   4.377 -
   4.378 -    assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
   4.379 -           == PGP_REVOCATION_STATUS_REVOKED);
   4.380 -
   4.381 -    status = tpk_save(session, tpk, NULL);
   4.382 -    tpk = NULL;
   4.383 -    ERROR_OUT(NULL, status, "Saving %s", fpr);
   4.384 -
   4.385 - out:
   4.386 -    pgp_signer_free (signer);
   4.387 -    pgp_key_pair_free (keypair);
   4.388 -    pgp_tpk_key_iter_free (iter);
   4.389 -    pgp_tpk_free(tpk);
   4.390 -
   4.391 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   4.392 -    return status;
   4.393 -}
   4.394 -
   4.395 -PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
   4.396 -                           const time_t when, bool *expired)
   4.397 -{
   4.398 -    PEP_STATUS status = PEP_STATUS_OK;
   4.399 -    pgp_tpk_t tpk = NULL;
   4.400 -    T("(%s)", fpr);
   4.401 -
   4.402 -    assert(session);
   4.403 -    assert(fpr);
   4.404 -    assert(expired);
   4.405 -
   4.406 -    *expired = false;
   4.407 -
   4.408 -    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   4.409 -    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   4.410 -    pgp_fingerprint_free(pgp_fpr);
   4.411 -    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   4.412 -
   4.413 -    // Is the TPK live?
   4.414 -    *expired = !pgp_tpk_alive_at(tpk, when);
   4.415 -#ifdef TRACING
   4.416 -    {
   4.417 -        char buffer[26];
   4.418 -        time_t now = time(NULL);
   4.419 -
   4.420 -        if (when == now || when == now - 1) {
   4.421 -            sprintf(buffer, "now");
   4.422 -        } else {
   4.423 -            struct tm tm;
   4.424 -            gmtime_r(&when, &tm);
   4.425 -            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
   4.426 -        }
   4.427 -
   4.428 -        T("TPK is %slive as of %s", *expired ? "not " : "", buffer);
   4.429 -    }
   4.430 -#endif
   4.431 -    if (*expired)
   4.432 -        goto out;
   4.433 -
   4.434 -    // Are there at least one certification subkey, one signing subkey
   4.435 -    // and one encryption subkey that are live?
   4.436 -    int can_certify = 0, can_encrypt = 0, can_sign = 0;
   4.437 -
   4.438 -    pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
   4.439 -    pgp_key_t key;
   4.440 -    pgp_signature_t sig;
   4.441 -    pgp_revocation_status_t rev;
   4.442 -    while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
   4.443 -        if (! sig)
   4.444 -            continue;
   4.445 -
   4.446 -        if (pgp_signature_can_encrypt_for_transport(sig)
   4.447 -            || pgp_signature_can_encrypt_at_rest(sig))
   4.448 -            can_encrypt = 1;
   4.449 -        if (pgp_signature_can_sign(sig))
   4.450 -            can_sign = 1;
   4.451 -        if (pgp_signature_can_certify(sig))
   4.452 -            can_certify = 1;
   4.453 -
   4.454 -        if (can_encrypt && can_sign && can_certify)
   4.455 -            break;
   4.456 -    }
   4.457 -    pgp_tpk_key_iter_free(key_iter);
   4.458 -
   4.459 -    *expired = !(can_encrypt && can_sign && can_certify);
   4.460 -
   4.461 -    T("Key can%s encrypt, can%s sign, can%s certify => %sexpired",
   4.462 -      can_encrypt ? "" : "not",
   4.463 -      can_sign ? "" : "not",
   4.464 -      can_certify ? "" : "not",
   4.465 -      *expired ? "" : "not ");
   4.466 -
   4.467 - out:
   4.468 -    pgp_tpk_free(tpk);
   4.469 -    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   4.470 -    return status;
   4.471 -}
   4.472 -
   4.473 -PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
   4.474 -{
   4.475 -    PEP_STATUS status = PEP_STATUS_OK;
   4.476 -    pgp_tpk_t tpk;
   4.477 -
   4.478 -    T("(%s)", fpr);
   4.479 -
   4.480 -    assert(session);
   4.481 -    assert(fpr);
   4.482 -    assert(revoked);
   4.483 -
   4.484 -    *revoked = false;
   4.485 -
   4.486 -    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   4.487 -    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   4.488 -    pgp_fingerprint_free(pgp_fpr);
   4.489 -    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   4.490 -
   4.491 -    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   4.492 -    *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
   4.493 -    pgp_revocation_status_free (rs);
   4.494 -    pgp_tpk_free(tpk);
   4.495 -
   4.496 - out:
   4.497 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   4.498 -    return status;
   4.499 -}
   4.500 -
   4.501  PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
   4.502  {
   4.503      PEP_STATUS status = PEP_STATUS_OK;
     5.1 --- a/sync/gen_message_func.ysl2	Tue Jul 09 11:24:18 2019 +0200
     5.2 +++ b/sync/gen_message_func.ysl2	Wed Aug 07 11:55:15 2019 +0200
     5.3 @@ -297,6 +297,20 @@
     5.4                   = session->«$state».«@name»;
     5.5  
     5.6          ||
     5.7 +        when "@type='Identity'"
     5.8 +        ||
     5.9 +        {
    5.10 +            pEp_identity *ident = Identity_to_Struct(&session->«$state».«@name», NULL);
    5.11 +            if (!ident)
    5.12 +                return PEP_OUT_OF_MEMORY;
    5.13 +            Identity_t *_ident = Identity_from_Struct(ident,
    5.14 +                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»);
    5.15 +            free_identity(ident);
    5.16 +            if (!_ident)
    5.17 +                return PEP_OUT_OF_MEMORY;
    5.18 +        }
    5.19 +
    5.20 +        ||
    5.21          when "@type='IdentityList'"
    5.22          ||
    5.23          {
    5.24 @@ -362,6 +376,21 @@
    5.25                  .choice.«$message_name».«@name»;
    5.26  
    5.27          ||
    5.28 +        when "@type='Identity'"
    5.29 +        ||
    5.30 +        {
    5.31 +            pEp_identity *ident = Identity_to_Struct(
    5.32 +                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name», NULL);
    5.33 +            if (!ident)
    5.34 +                return PEP_OUT_OF_MEMORY;
    5.35 +            Identity_t *_ident = Identity_from_Struct(ident,
    5.36 +                    &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
    5.37 +            free_identity(ident);
    5.38 +            if (!_ident)
    5.39 +                return PEP_OUT_OF_MEMORY;
    5.40 +        }
    5.41 +
    5.42 +        ||
    5.43          when "@type='IdentityList'"
    5.44          ||
    5.45          {
     6.1 --- a/sync/gen_statemachine.ysl2	Tue Jul 09 11:24:18 2019 +0200
     6.2 +++ b/sync/gen_statemachine.ysl2	Wed Aug 07 11:55:15 2019 +0200
     6.3 @@ -552,6 +552,7 @@
     6.4                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
     6.5                                  goto the_end;
     6.6                              }
     6.7 +                            add_opt_field(m, "pEp-auto-consume", "yes");
     6.8                              free_message(_m);
     6.9                              break;
    6.10  
    6.11 @@ -729,6 +730,7 @@
    6.12                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    6.13                                  goto the_end;
    6.14                              }
    6.15 +                            add_opt_field(m, "pEp-auto-consume", "yes");
    6.16                              free_message(_m);
    6.17                              break;
    6.18  
    6.19 @@ -752,6 +754,7 @@
    6.20                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    6.21                                  goto the_end;
    6.22                              }
    6.23 +                            add_opt_field(m, "pEp-auto-consume", "yes");
    6.24                              free_message(_m);
    6.25                      }
    6.26  
    6.27 @@ -1046,8 +1049,10 @@
    6.28  
    6.29          // state machine
    6.30  
    6.31 +        #ifndef NDEBUG
    6.32          const char *«@name»_state_name(int state);
    6.33          const char *«@name»_event_name(int event);
    6.34 +        #endif
    6.35  
    6.36          // the state machine function is returning the next state in case of a
    6.37          // transition or None for staying
    6.38 @@ -1073,6 +1078,9 @@
    6.39          #include "«@name»_fsm.h"
    6.40          #include <stdlib.h>
    6.41  
    6.42 +        #ifdef NDEBUG
    6.43 +        static
    6.44 +        #endif
    6.45          const char *«@name»_state_name(int state)
    6.46          {
    6.47              switch (state) {
    6.48 @@ -1093,6 +1101,9 @@
    6.49              }
    6.50          }
    6.51  
    6.52 +        #ifdef NDEBUG
    6.53 +        static
    6.54 +        #endif
    6.55          const char *«@name»_event_name(int event)
    6.56          {
    6.57              switch (event) {
    6.58 @@ -1158,7 +1169,7 @@
    6.59              switch (state) {
    6.60                  `` apply "state", 2, mode=fsm
    6.61                  default:
    6.62 -                    «@name»_ERR_LOG_INT("invalid state", state);
    6.63 +                    «@name»_ERR_LOG("invalid state", «@name»_state_name(state));
    6.64                      return invalid_state;
    6.65              }
    6.66              
     7.1 --- a/sync/sync.fsm	Tue Jul 09 11:24:18 2019 +0200
     7.2 +++ b/sync/sync.fsm	Wed Aug 07 11:55:15 2019 +0200
     7.3 @@ -10,7 +10,7 @@
     7.4  protocol Sync 1 {
     7.5      // all messages have a timestamp, time out and are removed after timeout
     7.6  
     7.7 -    fsm KeySync 1, threshold=60 {
     7.8 +    fsm KeySync 1, threshold=300 {
     7.9          version 1, 2;
    7.10  
    7.11          state InitState {
     8.1 --- a/test/src/engine_tests/IOS1664Tests.cc	Tue Jul 09 11:24:18 2019 +0200
     8.2 +++ b/test/src/engine_tests/IOS1664Tests.cc	Wed Aug 07 11:55:15 2019 +0200
     8.3 @@ -62,11 +62,11 @@
     8.4      TEST_ASSERT(status == PEP_STATUS_OK);
     8.5      TEST_ASSERT_MSG(rating == PEP_rating_trusted_and_anonymized, tl_rating_string(rating));
     8.6      status = identity_rating(session, out_msg->to->ident, &rating);
     8.7 -    TEST_ASSERT_MSG(status == PEP_KEY_NOT_FOUND, tl_status_string(status));
     8.8 -    TEST_ASSERT_MSG(rating == PEP_rating_undefined, tl_rating_string(rating));
     8.9 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
    8.10 +    TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
    8.11  
    8.12      status = outgoing_message_rating(session, out_msg, &rating);
    8.13 -    TEST_ASSERT(rating == PEP_rating_unencrypted);
    8.14 +    TEST_ASSERT(rating == PEP_rating_reliable);
    8.15      
    8.16      TEST_ASSERT(true);
    8.17  }