merge sync IOS-1576
authorbuff <andreas@pep-project.org>
Wed, 10 Jul 2019 11:44:43 +0200
branchIOS-1576
changeset 3929408594db81f1
parent 3928 117be5371dd4
parent 3922 a2ebf83845c9
child 3930 dbd227c0fef8
merge sync
     1.1 --- a/src/pEpEngine.c	Mon Jul 08 16:44:35 2019 +0200
     1.2 +++ b/src/pEpEngine.c	Wed Jul 10 11:44:43 2019 +0200
     1.3 @@ -4247,27 +4247,8 @@
     1.4      if (!(session && pattern && keylist))
     1.5          return PEP_ILLEGAL_VALUE;
     1.6  
     1.7 -    PEP_STATUS status = session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
     1.8 -                                                                         keylist);
     1.9 -                                                                         
    1.10 -#ifndef USE_GPG
    1.11 -    if (*keylist == NULL) {
    1.12 -        // we have a problem, in that older GPG keys with no username associated don't 
    1.13 -        // quote out the address-as-username, meaning the uid is non-standard.
    1.14 -        // sequoia then stores the whole uid string for lookup, so we try again here with 
    1.15 -        // a whole-uid-pattern:
    1.16 -        if (strchr(pattern, '@')) {
    1.17 -            char* new_pattern = calloc(2*strlen(pattern) + 4, 1);
    1.18 -            int n = sprintf(new_pattern, "%s <%s>", pattern, pattern);
    1.19 -            if (n > 0)
    1.20 -                status = session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, new_pattern,
    1.21 -                                                                          keylist);
    1.22 -            free(new_pattern);                                                                      
    1.23 -        }    
    1.24 -    }
    1.25 -#endif 
    1.26 -    
    1.27 -    return status;
    1.28 +    return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
    1.29 +            keylist);
    1.30  }
    1.31  
    1.32  
     2.1 --- a/src/pgp_sequoia.c	Mon Jul 08 16:44:35 2019 +0200
     2.2 +++ b/src/pgp_sequoia.c	Wed Jul 10 11:44:43 2019 +0200
     2.3 @@ -1447,6 +1447,33 @@
     2.4      if (size == 0 || sig_size == 0)
     2.5          return PEP_DECRYPT_WRONG_FORMAT;
     2.6  
     2.7 +#if TRACING > 0
     2.8 +    {
     2.9 +        int cr = 0;
    2.10 +        int crlf = 0;
    2.11 +        int lf = 0;
    2.12 +
    2.13 +        for (int i = 0; i < size; i ++) {
    2.14 +            // CR
    2.15 +            if (text[i] == '\r') {
    2.16 +                cr ++;
    2.17 +            }
    2.18 +            // LF
    2.19 +            if (text[i] == '\n') {
    2.20 +                if (i > 0 && text[i - 1] == '\r') {
    2.21 +                    cr --;
    2.22 +                    crlf ++;
    2.23 +                } else {
    2.24 +                    lf ++;
    2.25 +                }
    2.26 +            }
    2.27 +        }
    2.28 +
    2.29 +        T("Text to verify: %zd bytes with %d crlfs, %d bare crs and %d bare lfs",
    2.30 +          size, crlf, cr, lf);
    2.31 +    }
    2.32 +#endif
    2.33 +
    2.34      cookie.recipient_keylist = new_stringlist(NULL);
    2.35      if (!cookie.recipient_keylist)
    2.36          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    2.37 @@ -2366,6 +2393,245 @@
    2.38      return PEP_UNKNOWN_ERROR;
    2.39  }
    2.40  
    2.41 +
    2.42 +PEP_STATUS pgp_renew_key(
    2.43 +    PEP_SESSION session, const char *fpr, const timestamp *ts)
    2.44 +{
    2.45 +    PEP_STATUS status = PEP_STATUS_OK;
    2.46 +    pgp_error_t err = NULL;
    2.47 +    pgp_tpk_t tpk = NULL;
    2.48 +    pgp_tpk_key_iter_t iter = NULL;
    2.49 +    pgp_key_pair_t keypair = NULL;
    2.50 +    pgp_signer_t signer = NULL;
    2.51 +    time_t t = mktime((struct tm *) ts);
    2.52 +
    2.53 +    T("(%s)", fpr);
    2.54 +
    2.55 +    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
    2.56 +    ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
    2.57 +
    2.58 +    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
    2.59 +    if (creation_time > t)
    2.60 +        // The creation time is after the expiration time!
    2.61 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
    2.62 +                  "creation time can't be after expiration time");
    2.63 +
    2.64 +    uint32_t delta = t - creation_time;
    2.65 +
    2.66 +
    2.67 +    iter = pgp_tpk_key_iter_valid(tpk);
    2.68 +    pgp_tpk_key_iter_certification_capable (iter);
    2.69 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
    2.70 +
    2.71 +    // If there are multiple certification capable subkeys, we just
    2.72 +    // take the first one, whichever one that happens to be.
    2.73 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
    2.74 +    if (! key)
    2.75 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
    2.76 +                   "%s has no usable certification capable key", fpr);
    2.77 +
    2.78 +    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
    2.79 +    if (! keypair)
    2.80 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
    2.81 +
    2.82 +    signer = pgp_key_pair_as_signer (keypair);
    2.83 +    if (! signer)
    2.84 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
    2.85 +
    2.86 +    tpk = pgp_tpk_set_expiry(&err, tpk, signer, delta);
    2.87 +    if (! tpk)
    2.88 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
    2.89 +
    2.90 +    status = tpk_save(session, tpk, NULL);
    2.91 +    tpk = NULL;
    2.92 +    ERROR_OUT(NULL, status, "Saving %s", fpr);
    2.93 +
    2.94 + out:
    2.95 +    pgp_signer_free (signer);
    2.96 +    pgp_key_pair_free (keypair);
    2.97 +    pgp_tpk_key_iter_free (iter);
    2.98 +    pgp_tpk_free(tpk);
    2.99 +
   2.100 +    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   2.101 +    return status;
   2.102 +}
   2.103 +
   2.104 +PEP_STATUS pgp_revoke_key(
   2.105 +    PEP_SESSION session, const char *fpr, const char *reason)
   2.106 +{
   2.107 +    PEP_STATUS status = PEP_STATUS_OK;
   2.108 +    pgp_error_t err = NULL;
   2.109 +    pgp_tpk_t tpk = NULL;
   2.110 +    pgp_tpk_key_iter_t iter = NULL;
   2.111 +    pgp_key_pair_t keypair = NULL;
   2.112 +    pgp_signer_t signer = NULL;
   2.113 +
   2.114 +    T("(%s)", fpr);
   2.115 +
   2.116 +    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
   2.117 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   2.118 +
   2.119 +    iter = pgp_tpk_key_iter_valid(tpk);
   2.120 +    pgp_tpk_key_iter_certification_capable (iter);
   2.121 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
   2.122 +
   2.123 +    // If there are multiple certification capable subkeys, we just
   2.124 +    // take the first one, whichever one that happens to be.
   2.125 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
   2.126 +    if (! key)
   2.127 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   2.128 +                   "%s has no usable certification capable key", fpr);
   2.129 +
   2.130 +    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   2.131 +    if (! keypair)
   2.132 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
   2.133 +
   2.134 +    signer = pgp_key_pair_as_signer (keypair);
   2.135 +    if (! signer)
   2.136 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
   2.137 +
   2.138 +    tpk = pgp_tpk_revoke_in_place(&err, tpk, signer,
   2.139 +                                  PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
   2.140 +                                  reason);
   2.141 +    if (! tpk)
   2.142 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   2.143 +
   2.144 +    assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
   2.145 +           == PGP_REVOCATION_STATUS_REVOKED);
   2.146 +
   2.147 +    status = tpk_save(session, tpk, NULL);
   2.148 +    tpk = NULL;
   2.149 +    ERROR_OUT(NULL, status, "Saving %s", fpr);
   2.150 +
   2.151 + out:
   2.152 +    pgp_signer_free (signer);
   2.153 +    pgp_key_pair_free (keypair);
   2.154 +    pgp_tpk_key_iter_free (iter);
   2.155 +    pgp_tpk_free(tpk);
   2.156 +
   2.157 +    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   2.158 +    return status;
   2.159 +}
   2.160 +
   2.161 +static void _pgp_key_expired(pgp_tpk_t tpk, const time_t when, bool* expired)
   2.162 +{
   2.163 +    // Is the TPK live?
   2.164 +    *expired = !pgp_tpk_alive_at(tpk, when);
   2.165 +
   2.166 +#ifdef TRACING
   2.167 +    {
   2.168 +        char buffer[26];
   2.169 +        time_t now = time(NULL);
   2.170 +
   2.171 +        if (when == now || when == now - 1) {
   2.172 +            sprintf(buffer, "now");
   2.173 +        } else {
   2.174 +            struct tm tm;
   2.175 +            gmtime_r(&when, &tm);
   2.176 +            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
   2.177 +        }
   2.178 +
   2.179 +        T("TPK is %slive as of %s", *expired ? "not " : "", buffer);
   2.180 +    }
   2.181 +#endif
   2.182 +    if (*expired)
   2.183 +        goto out;
   2.184 +
   2.185 +    // Are there at least one certification subkey, one signing subkey
   2.186 +    // and one encryption subkey that are live?
   2.187 +    //    int can_certify = 0, can_encrypt = 0, can_sign = 0;
   2.188 +    int can_encrypt = 0, can_sign = 0;
   2.189 +
   2.190 +    pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
   2.191 +    pgp_key_t key;
   2.192 +    pgp_signature_t sig;
   2.193 +    pgp_revocation_status_t rev;
   2.194 +    while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
   2.195 +        if (! sig)
   2.196 +            continue;
   2.197 +
   2.198 +        if (pgp_signature_can_encrypt_for_transport(sig)
   2.199 +            || pgp_signature_can_encrypt_at_rest(sig))
   2.200 +            can_encrypt = 1;
   2.201 +        if (pgp_signature_can_sign(sig))
   2.202 +            can_sign = 1;
   2.203 +        // if (pgp_signature_can_certify(sig))
   2.204 +        //     can_certify = 1;
   2.205 +
   2.206 +//        if (can_encrypt && can_sign && can_certify)
   2.207 +        if (can_encrypt && can_sign)
   2.208 +            break;
   2.209 +    }
   2.210 +    pgp_tpk_key_iter_free(key_iter);
   2.211 +
   2.212 +//    *expired = !(can_encrypt && can_sign && can_certify);
   2.213 +    *expired = !(can_encrypt && can_sign);
   2.214 +
   2.215 +    T("Key can%s encrypt, can%s sign, can%s certify => %sexpired",
   2.216 +      can_encrypt ? "" : "not",
   2.217 +      can_sign ? "" : "not",
   2.218 +      // can_certify ? "" : "not",
   2.219 +      *expired ? "" : "not ");
   2.220 +      
   2.221 +out:
   2.222 +    // Er, this might be problematic in terms of internal vs. external in log. FIXME?
   2.223 +    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   2.224 +    return;
   2.225 +}
   2.226 +                            
   2.227 +PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
   2.228 +                           const time_t when, bool *expired)
   2.229 +{
   2.230 +    PEP_STATUS status = PEP_STATUS_OK;
   2.231 +    pgp_tpk_t tpk = NULL;
   2.232 +    T("(%s)", fpr);
   2.233 +
   2.234 +    assert(session);
   2.235 +    assert(fpr);
   2.236 +    assert(expired);
   2.237 +
   2.238 +    *expired = false;
   2.239 +
   2.240 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   2.241 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   2.242 +    pgp_fingerprint_free(pgp_fpr);
   2.243 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   2.244 +
   2.245 +    _pgp_key_expired(tpk, when, expired);
   2.246 + out:
   2.247 +    pgp_tpk_free(tpk);
   2.248 +    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   2.249 +    return status;
   2.250 +}
   2.251 +
   2.252 +PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
   2.253 +{
   2.254 +    PEP_STATUS status = PEP_STATUS_OK;
   2.255 +    pgp_tpk_t tpk;
   2.256 +
   2.257 +    T("(%s)", fpr);
   2.258 +
   2.259 +    assert(session);
   2.260 +    assert(fpr);
   2.261 +    assert(revoked);
   2.262 +
   2.263 +    *revoked = false;
   2.264 +
   2.265 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   2.266 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   2.267 +    pgp_fingerprint_free(pgp_fpr);
   2.268 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   2.269 +
   2.270 +    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   2.271 +    *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
   2.272 +    pgp_revocation_status_free (rs);
   2.273 +    pgp_tpk_free(tpk);
   2.274 +
   2.275 + out:
   2.276 +    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   2.277 +    return status;
   2.278 +}
   2.279 +
   2.280  PEP_STATUS pgp_get_key_rating(
   2.281      PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
   2.282  {
   2.283 @@ -2385,10 +2651,20 @@
   2.284  
   2.285      *comm_type = PEP_ct_OpenPGP_unconfirmed;
   2.286  
   2.287 -    if (pgp_tpk_expired(tpk)) {
   2.288 +    bool expired = false;
   2.289 +    
   2.290 +    // MUST guarantee the same behaviour.
   2.291 +    _pgp_key_expired(tpk, time(NULL), &expired);
   2.292 +    
   2.293 +    if (expired) {
   2.294          *comm_type = PEP_ct_key_expired;
   2.295 -        goto out;
   2.296 +        goto out;        
   2.297      }
   2.298 +    
   2.299 +    // if (pgp_tpk_expired(tpk)) {
   2.300 +    //     *comm_type = PEP_ct_key_expired;
   2.301 +    //     goto out;
   2.302 +    // }
   2.303  
   2.304      pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   2.305      pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
   2.306 @@ -2451,231 +2727,6 @@
   2.307  }
   2.308  
   2.309  
   2.310 -PEP_STATUS pgp_renew_key(
   2.311 -    PEP_SESSION session, const char *fpr, const timestamp *ts)
   2.312 -{
   2.313 -    PEP_STATUS status = PEP_STATUS_OK;
   2.314 -    pgp_error_t err = NULL;
   2.315 -    pgp_tpk_t tpk = NULL;
   2.316 -    pgp_tpk_key_iter_t iter = NULL;
   2.317 -    pgp_key_pair_t keypair = NULL;
   2.318 -    pgp_signer_t signer = NULL;
   2.319 -    time_t t = mktime((struct tm *) ts);
   2.320 -
   2.321 -    T("(%s)", fpr);
   2.322 -
   2.323 -    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
   2.324 -    ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
   2.325 -
   2.326 -    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
   2.327 -    if (creation_time > t)
   2.328 -        // The creation time is after the expiration time!
   2.329 -        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   2.330 -                  "creation time can't be after expiration time");
   2.331 -
   2.332 -    uint32_t delta = t - creation_time;
   2.333 -
   2.334 -
   2.335 -    iter = pgp_tpk_key_iter_valid(tpk);
   2.336 -    pgp_tpk_key_iter_certification_capable (iter);
   2.337 -    pgp_tpk_key_iter_unencrypted_secret (iter, true);
   2.338 -
   2.339 -    // If there are multiple certification capable subkeys, we just
   2.340 -    // take the first one, whichever one that happens to be.
   2.341 -    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
   2.342 -    if (! key)
   2.343 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   2.344 -                   "%s has no usable certification capable key", fpr);
   2.345 -
   2.346 -    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   2.347 -    if (! keypair)
   2.348 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
   2.349 -
   2.350 -    signer = pgp_key_pair_as_signer (keypair);
   2.351 -    if (! signer)
   2.352 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
   2.353 -
   2.354 -    tpk = pgp_tpk_set_expiry(&err, tpk, signer, delta);
   2.355 -    if (! tpk)
   2.356 -        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   2.357 -
   2.358 -    status = tpk_save(session, tpk, NULL);
   2.359 -    tpk = NULL;
   2.360 -    ERROR_OUT(NULL, status, "Saving %s", fpr);
   2.361 -
   2.362 - out:
   2.363 -    pgp_signer_free (signer);
   2.364 -    pgp_key_pair_free (keypair);
   2.365 -    pgp_tpk_key_iter_free (iter);
   2.366 -    pgp_tpk_free(tpk);
   2.367 -
   2.368 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   2.369 -    return status;
   2.370 -}
   2.371 -
   2.372 -PEP_STATUS pgp_revoke_key(
   2.373 -    PEP_SESSION session, const char *fpr, const char *reason)
   2.374 -{
   2.375 -    PEP_STATUS status = PEP_STATUS_OK;
   2.376 -    pgp_error_t err = NULL;
   2.377 -    pgp_tpk_t tpk = NULL;
   2.378 -    pgp_tpk_key_iter_t iter = NULL;
   2.379 -    pgp_key_pair_t keypair = NULL;
   2.380 -    pgp_signer_t signer = NULL;
   2.381 -
   2.382 -    T("(%s)", fpr);
   2.383 -
   2.384 -    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
   2.385 -    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   2.386 -
   2.387 -    iter = pgp_tpk_key_iter_valid(tpk);
   2.388 -    pgp_tpk_key_iter_certification_capable (iter);
   2.389 -    pgp_tpk_key_iter_unencrypted_secret (iter, true);
   2.390 -
   2.391 -    // If there are multiple certification capable subkeys, we just
   2.392 -    // take the first one, whichever one that happens to be.
   2.393 -    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
   2.394 -    if (! key)
   2.395 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   2.396 -                   "%s has no usable certification capable key", fpr);
   2.397 -
   2.398 -    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   2.399 -    if (! keypair)
   2.400 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
   2.401 -
   2.402 -    signer = pgp_key_pair_as_signer (keypair);
   2.403 -    if (! signer)
   2.404 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
   2.405 -
   2.406 -    tpk = pgp_tpk_revoke_in_place(&err, tpk, signer,
   2.407 -                                  PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
   2.408 -                                  reason);
   2.409 -    if (! tpk)
   2.410 -        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   2.411 -
   2.412 -    assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
   2.413 -           == PGP_REVOCATION_STATUS_REVOKED);
   2.414 -
   2.415 -    status = tpk_save(session, tpk, NULL);
   2.416 -    tpk = NULL;
   2.417 -    ERROR_OUT(NULL, status, "Saving %s", fpr);
   2.418 -
   2.419 - out:
   2.420 -    pgp_signer_free (signer);
   2.421 -    pgp_key_pair_free (keypair);
   2.422 -    pgp_tpk_key_iter_free (iter);
   2.423 -    pgp_tpk_free(tpk);
   2.424 -
   2.425 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   2.426 -    return status;
   2.427 -}
   2.428 -
   2.429 -PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
   2.430 -                           const time_t when, bool *expired)
   2.431 -{
   2.432 -    PEP_STATUS status = PEP_STATUS_OK;
   2.433 -    pgp_tpk_t tpk = NULL;
   2.434 -    T("(%s)", fpr);
   2.435 -
   2.436 -    assert(session);
   2.437 -    assert(fpr);
   2.438 -    assert(expired);
   2.439 -
   2.440 -    *expired = false;
   2.441 -
   2.442 -    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   2.443 -    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   2.444 -    pgp_fingerprint_free(pgp_fpr);
   2.445 -    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   2.446 -
   2.447 -    // Is the TPK live?
   2.448 -    *expired = !pgp_tpk_alive_at(tpk, when);
   2.449 -#ifdef TRACING
   2.450 -    {
   2.451 -        char buffer[26];
   2.452 -        time_t now = time(NULL);
   2.453 -
   2.454 -        if (when == now || when == now - 1) {
   2.455 -            sprintf(buffer, "now");
   2.456 -        } else {
   2.457 -            struct tm tm;
   2.458 -            gmtime_r(&when, &tm);
   2.459 -            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
   2.460 -        }
   2.461 -
   2.462 -        T("TPK is %slive as of %s", *expired ? "not " : "", buffer);
   2.463 -    }
   2.464 -#endif
   2.465 -    if (*expired)
   2.466 -        goto out;
   2.467 -
   2.468 -    // Are there at least one certification subkey, one signing subkey
   2.469 -    // and one encryption subkey that are live?
   2.470 -    int can_certify = 0, can_encrypt = 0, can_sign = 0;
   2.471 -
   2.472 -    pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
   2.473 -    pgp_key_t key;
   2.474 -    pgp_signature_t sig;
   2.475 -    pgp_revocation_status_t rev;
   2.476 -    while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
   2.477 -        if (! sig)
   2.478 -            continue;
   2.479 -
   2.480 -        if (pgp_signature_can_encrypt_for_transport(sig)
   2.481 -            || pgp_signature_can_encrypt_at_rest(sig))
   2.482 -            can_encrypt = 1;
   2.483 -        if (pgp_signature_can_sign(sig))
   2.484 -            can_sign = 1;
   2.485 -        if (pgp_signature_can_certify(sig))
   2.486 -            can_certify = 1;
   2.487 -
   2.488 -        if (can_encrypt && can_sign && can_certify)
   2.489 -            break;
   2.490 -    }
   2.491 -    pgp_tpk_key_iter_free(key_iter);
   2.492 -
   2.493 -    *expired = !(can_encrypt && can_sign && can_certify);
   2.494 -
   2.495 -    T("Key can%s encrypt, can%s sign, can%s certify => %sexpired",
   2.496 -      can_encrypt ? "" : "not",
   2.497 -      can_sign ? "" : "not",
   2.498 -      can_certify ? "" : "not",
   2.499 -      *expired ? "" : "not ");
   2.500 -
   2.501 - out:
   2.502 -    pgp_tpk_free(tpk);
   2.503 -    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   2.504 -    return status;
   2.505 -}
   2.506 -
   2.507 -PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
   2.508 -{
   2.509 -    PEP_STATUS status = PEP_STATUS_OK;
   2.510 -    pgp_tpk_t tpk;
   2.511 -
   2.512 -    T("(%s)", fpr);
   2.513 -
   2.514 -    assert(session);
   2.515 -    assert(fpr);
   2.516 -    assert(revoked);
   2.517 -
   2.518 -    *revoked = false;
   2.519 -
   2.520 -    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   2.521 -    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
   2.522 -    pgp_fingerprint_free(pgp_fpr);
   2.523 -    ERROR_OUT(NULL, status, "Looking up %s", fpr);
   2.524 -
   2.525 -    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   2.526 -    *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
   2.527 -    pgp_revocation_status_free (rs);
   2.528 -    pgp_tpk_free(tpk);
   2.529 -
   2.530 - out:
   2.531 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   2.532 -    return status;
   2.533 -}
   2.534 -
   2.535  PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
   2.536  {
   2.537      PEP_STATUS status = PEP_STATUS_OK;
     3.1 --- a/sync/gen_statemachine.ysl2	Mon Jul 08 16:44:35 2019 +0200
     3.2 +++ b/sync/gen_statemachine.ysl2	Wed Jul 10 11:44:43 2019 +0200
     3.3 @@ -1046,8 +1046,10 @@
     3.4  
     3.5          // state machine
     3.6  
     3.7 +        #ifndef NDEBUG
     3.8          const char *«@name»_state_name(int state);
     3.9          const char *«@name»_event_name(int event);
    3.10 +        #endif
    3.11  
    3.12          // the state machine function is returning the next state in case of a
    3.13          // transition or None for staying
    3.14 @@ -1073,6 +1075,9 @@
    3.15          #include "«@name»_fsm.h"
    3.16          #include <stdlib.h>
    3.17  
    3.18 +        #ifdef NDEBUG
    3.19 +        static
    3.20 +        #endif
    3.21          const char *«@name»_state_name(int state)
    3.22          {
    3.23              switch (state) {
    3.24 @@ -1093,6 +1098,9 @@
    3.25              }
    3.26          }
    3.27  
    3.28 +        #ifdef NDEBUG
    3.29 +        static
    3.30 +        #endif
    3.31          const char *«@name»_event_name(int event)
    3.32          {
    3.33              switch (event) {
    3.34 @@ -1158,7 +1166,7 @@
    3.35              switch (state) {
    3.36                  `` apply "state", 2, mode=fsm
    3.37                  default:
    3.38 -                    «@name»_ERR_LOG_INT("invalid state", state);
    3.39 +                    «@name»_ERR_LOG("invalid state", «@name»_state_name(state));
    3.40                      return invalid_state;
    3.41              }
    3.42              
     4.1 --- a/test/src/SuiteMaker.cc	Mon Jul 08 16:44:35 2019 +0200
     4.2 +++ b/test/src/SuiteMaker.cc	Wed Jul 10 11:44:43 2019 +0200
     4.3 @@ -21,6 +21,7 @@
     4.4  #include "Engine463Tests.h"
     4.5  #include "IOS1664Tests.h"
     4.6  #include "BloblistTests.h"
     4.7 +#include "KeyImportAndRetrieveTests.h"
     4.8  #include "NewUpdateIdAndMyselfTests.h"
     4.9  #include "NoOwnIdentWritesOnDecryptTests.h"
    4.10  #include "LiteralFilenameTests.h"
    4.11 @@ -29,6 +30,7 @@
    4.12  #include "PgpBinaryTests.h"
    4.13  #include "SubkeyRatingEvalTests.h"
    4.14  #include "MessageNullFromTests.h"
    4.15 +#include "Engine587Tests.h"
    4.16  #include "ExportKeyTests.h"
    4.17  #include "LeastCommonDenomColorTests.h"
    4.18  #include "StringlistTests.h"
    4.19 @@ -87,6 +89,7 @@
    4.20      "Engine463Tests",
    4.21      "IOS1664Tests",
    4.22      "BloblistTests",
    4.23 +    "KeyImportAndRetrieveTests",
    4.24      "NewUpdateIdAndMyselfTests",
    4.25      "NoOwnIdentWritesOnDecryptTests",
    4.26      "LiteralFilenameTests",
    4.27 @@ -95,6 +98,7 @@
    4.28      "PgpBinaryTests",
    4.29      "SubkeyRatingEvalTests",
    4.30      "MessageNullFromTests",
    4.31 +    "Engine587Tests",
    4.32      "ExportKeyTests",
    4.33      "LeastCommonDenomColorTests",
    4.34      "StringlistTests",
    4.35 @@ -144,7 +148,7 @@
    4.36  };
    4.37  
    4.38  // This file is generated, so magic constants are ok.
    4.39 -int SuiteMaker::num_suites = 63;
    4.40 +int SuiteMaker::num_suites = 65;
    4.41  
    4.42  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
    4.43      if (strcmp(test_class_name, "URIAddressTests") == 0)
    4.44 @@ -165,6 +169,8 @@
    4.45          *test_suite = new IOS1664Tests(test_class_name, test_home);
    4.46      else if (strcmp(test_class_name, "BloblistTests") == 0)
    4.47          *test_suite = new BloblistTests(test_class_name, test_home);
    4.48 +    else if (strcmp(test_class_name, "KeyImportAndRetrieveTests") == 0)
    4.49 +        *test_suite = new KeyImportAndRetrieveTests(test_class_name, test_home);
    4.50      else if (strcmp(test_class_name, "NewUpdateIdAndMyselfTests") == 0)
    4.51          *test_suite = new NewUpdateIdAndMyselfTests(test_class_name, test_home);
    4.52      else if (strcmp(test_class_name, "NoOwnIdentWritesOnDecryptTests") == 0)
    4.53 @@ -181,6 +187,8 @@
    4.54          *test_suite = new SubkeyRatingEvalTests(test_class_name, test_home);
    4.55      else if (strcmp(test_class_name, "MessageNullFromTests") == 0)
    4.56          *test_suite = new MessageNullFromTests(test_class_name, test_home);
    4.57 +    else if (strcmp(test_class_name, "Engine587Tests") == 0)
    4.58 +        *test_suite = new Engine587Tests(test_class_name, test_home);
    4.59      else if (strcmp(test_class_name, "ExportKeyTests") == 0)
    4.60          *test_suite = new ExportKeyTests(test_class_name, test_home);
    4.61      else if (strcmp(test_class_name, "LeastCommonDenomColorTests") == 0)
     5.1 --- a/test/src/engine_tests/IOS1664Tests.cc	Mon Jul 08 16:44:35 2019 +0200
     5.2 +++ b/test/src/engine_tests/IOS1664Tests.cc	Wed Jul 10 11:44:43 2019 +0200
     5.3 @@ -62,11 +62,11 @@
     5.4      TEST_ASSERT(status == PEP_STATUS_OK);
     5.5      TEST_ASSERT_MSG(rating == PEP_rating_trusted_and_anonymized, tl_rating_string(rating));
     5.6      status = identity_rating(session, out_msg->to->ident, &rating);
     5.7 -    TEST_ASSERT_MSG(status == PEP_KEY_NOT_FOUND, tl_status_string(status));
     5.8 -    TEST_ASSERT_MSG(rating == PEP_rating_undefined, tl_rating_string(rating));
     5.9 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
    5.10 +    TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
    5.11  
    5.12      status = outgoing_message_rating(session, out_msg, &rating);
    5.13 -    TEST_ASSERT(rating == PEP_rating_unencrypted);
    5.14 +    TEST_ASSERT(rating == PEP_rating_reliable);
    5.15      
    5.16      TEST_ASSERT(true);
    5.17  }