Top-level sign-only function, signing-related status returns ENGINE-633
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Mon, 23 Sep 2019 14:56:17 +0200
branchENGINE-633
changeset 408444135988583a
parent 4080 2f2d566db998
child 4085 47e056f8a2d7
Top-level sign-only function, signing-related status returns
src/message_api.c
src/message_api.h
src/pEpEngine.h
test/src/Engine358Test.cc
test/src/ExternalRevokeTest.cc
test/src/KeyResetMessageTest.cc
     1.1 --- a/src/message_api.c	Mon Sep 23 02:41:34 2019 +0200
     1.2 +++ b/src/message_api.c	Mon Sep 23 14:56:17 2019 +0200
     1.3 @@ -1742,6 +1742,132 @@
     1.4      }                   
     1.5  }
     1.6  
     1.7 +
     1.8 +DYNAMIC_API PEP_STATUS message_sign_only(
     1.9 +        PEP_SESSION session,
    1.10 +        message *src,
    1.11 +        message **dst
    1.12 +    )
    1.13 +{
    1.14 +    PEP_STATUS status = PEP_STATUS_OK;
    1.15 +    message * msg = NULL;
    1.16 +    message* _src = src;    
    1.17 +    
    1.18 +    assert(session);
    1.19 +    assert(src && src->from);
    1.20 +    assert(dst);
    1.21 +
    1.22 +    if (!(session && src && src->from && dst))
    1.23 +        return PEP_ILLEGAL_VALUE;
    1.24 +
    1.25 +    if (src->dir == PEP_dir_incoming)
    1.26 +        return PEP_ILLEGAL_VALUE;
    1.27 +
    1.28 +    *dst = NULL;
    1.29 +
    1.30 +    if (!src->from->user_id || src->from->user_id[0] == '\0') {
    1.31 +        char* own_id = NULL;
    1.32 +        status = get_default_own_userid(session, &own_id);
    1.33 +        if (own_id) {
    1.34 +            free(src->from->user_id);
    1.35 +            src->from->user_id = own_id; // ownership transfer
    1.36 +        }
    1.37 +    }
    1.38 +
    1.39 +    status = myself(session, src->from);
    1.40 +    
    1.41 +    if (status != PEP_STATUS_OK)
    1.42 +        goto pEp_error;
    1.43 +
    1.44 +    char* send_fpr = src->from->fpr;
    1.45 +    if (EMPTYSTR(send_fpr))
    1.46 +        return PEP_CANNOT_SIGN;
    1.47 +        
    1.48 +    identity_list * _il = NULL;
    1.49 +
    1.50 +    for (_il = src->to; _il && _il->ident; _il = _il->next) {
    1.51 +        PEP_STATUS _status = PEP_STATUS_OK;
    1.52 +        if (!is_me(session, _il->ident)) {
    1.53 +            // Do this to get saved user data (name, etc), not for keys here
    1.54 +            _status = update_identity(session, _il->ident);
    1.55 +            if (_status == PEP_CANNOT_FIND_IDENTITY)
    1.56 +                _status = PEP_STATUS_OK;
    1.57 +                        
    1.58 +            _status = bind_own_ident_with_contact_ident(session, src->from, _il->ident);
    1.59 +            if (_status != PEP_STATUS_OK) {
    1.60 +                status = PEP_UNKNOWN_DB_ERROR;
    1.61 +                goto pEp_error;
    1.62 +            }
    1.63 +        }
    1.64 +        else
    1.65 +            _status = myself(session, _il->ident);
    1.66 +            
    1.67 +        if (_status != PEP_STATUS_OK)
    1.68 +            goto pEp_error;
    1.69 +    }
    1.70 +
    1.71 +    for (_il = src->cc; _il && _il->ident; _il = _il->next) {
    1.72 +        PEP_STATUS _status = PEP_STATUS_OK;
    1.73 +        if (!is_me(session, _il->ident)) {
    1.74 +            // Do this to get saved user data (name, etc), not for keys here
    1.75 +            _status = update_identity(session, _il->ident);
    1.76 +            if (_status == PEP_CANNOT_FIND_IDENTITY)
    1.77 +                _status = PEP_STATUS_OK;
    1.78 +                        
    1.79 +            _status = bind_own_ident_with_contact_ident(session, src->from, _il->ident);
    1.80 +            if (_status != PEP_STATUS_OK) {
    1.81 +                status = PEP_UNKNOWN_DB_ERROR;
    1.82 +                goto pEp_error;
    1.83 +            }
    1.84 +        }
    1.85 +        else
    1.86 +            _status = myself(session, _il->ident);
    1.87 +            
    1.88 +        if (_status != PEP_STATUS_OK)
    1.89 +            goto pEp_error;
    1.90 +    }
    1.91 +    // We can do a whole BCC list since this is signing, not encrypting
    1.92 +    for (_il = src->bcc; _il && _il->ident; _il = _il->next) {
    1.93 +        PEP_STATUS _status = PEP_STATUS_OK;
    1.94 +        if (!is_me(session, _il->ident)) {
    1.95 +            // Do this to get saved user data (name, etc), not for keys here
    1.96 +            _status = update_identity(session, _il->ident);
    1.97 +            if (_status == PEP_CANNOT_FIND_IDENTITY)
    1.98 +                _status = PEP_STATUS_OK;
    1.99 +                        
   1.100 +            _status = bind_own_ident_with_contact_ident(session, src->from, _il->ident);
   1.101 +            if (_status != PEP_STATUS_OK) {
   1.102 +                status = PEP_UNKNOWN_DB_ERROR;
   1.103 +                goto pEp_error;
   1.104 +            }
   1.105 +        }
   1.106 +        else
   1.107 +            _status = myself(session, _il->ident);
   1.108 +            
   1.109 +        if (_status != PEP_STATUS_OK)
   1.110 +            goto pEp_error;
   1.111 +    }
   1.112 +
   1.113 +    msg = clone_to_empty_message(_src);                
   1.114 +    status = sign_PGP_MIME(session, _src, src->from->fpr, msg);
   1.115 +    if (status == PEP_STATUS_OK) {                
   1.116 +        msg->enc_format = PEP_enc_sign_only;
   1.117 +        *dst = msg;
   1.118 +        return PEP_SIGNED_ONLY;
   1.119 +    }
   1.120 +    else {
   1.121 +        status = PEP_CANNOT_SIGN;
   1.122 +        goto pEp_error;
   1.123 +    }    
   1.124 +    
   1.125 +pEp_error:
   1.126 +    free_message(msg);
   1.127 +    if (_src && _src != src)
   1.128 +        free_message(_src);
   1.129 +    return status;
   1.130 +}
   1.131 +
   1.132 +
   1.133  DYNAMIC_API PEP_STATUS encrypt_message(
   1.134          PEP_SESSION session,
   1.135          message *src,
   1.136 @@ -2019,16 +2145,12 @@
   1.137          // Now sign it
   1.138          if (!(flags & PEP_encrypt_flag_force_unsigned) 
   1.139              && (enc_format != PEP_enc_none) && !EMPTYSTR(src->from->fpr)) {
   1.140 -            msg = clone_to_empty_message(_src);                
   1.141 -            status = sign_PGP_MIME(session, _src, src->from->fpr, msg);
   1.142 -            if (status == PEP_STATUS_OK) {                
   1.143 -                msg->enc_format = PEP_enc_sign_only;
   1.144 -                *dst = msg;
   1.145 -            }
   1.146 -            else {
   1.147 -                status = PEP_CANNOT_SIGN;
   1.148 +            status = message_sign_only(session, src, dst);
   1.149 +            if (status != PEP_SIGNED_ONLY)
   1.150                  goto pEp_error;
   1.151 -            }    
   1.152 +
   1.153 +            _cleanup_src(src, added_key_to_real_src);
   1.154 +            return status;
   1.155          }
   1.156          return PEP_UNENCRYPTED;
   1.157      }
     2.1 --- a/src/message_api.h	Mon Sep 23 02:41:34 2019 +0200
     2.2 +++ b/src/message_api.h	Mon Sep 23 14:56:17 2019 +0200
     2.3 @@ -56,6 +56,27 @@
     2.4      PEP_message_key_reset   // for wrapped key reset information
     2.5  } message_wrap_type;
     2.6  
     2.7 +// message_sign_only() - sign message and return generated signature as well as encoded signed text
     2.8 +//
     2.9 +//  parameters:
    2.10 +//      session (in)        session handle
    2.11 +//      src (in)            message to sign
    2.12 +//      dst (out)           pointer to new signed message or NULL if no
    2.13 +//                          encryption could take place
    2.14 +//
    2.15 +//  return value:
    2.16 +//      PEP_SIGNED_ONLY                 on success
    2.17 +//      PEP_CANNOT_SIGN                 on failure
    2.18 +//
    2.19 +//  caveat:
    2.20 +//      the ownership of src remains with the caller
    2.21 +//      the ownership of dst goes to the caller
    2.22 +DYNAMIC_API PEP_STATUS message_sign_only(
    2.23 +        PEP_SESSION session,
    2.24 +        message *src,
    2.25 +        message **dst
    2.26 +    );
    2.27 +
    2.28  // encrypt_message() - encrypt message in memory
    2.29  //
    2.30  //  parameters:
    2.31 @@ -73,9 +94,13 @@
    2.32  //      PEP_STATUS_OK                   on success
    2.33  //      PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    2.34  //                                      an ambiguous name
    2.35 +//      PEP_SIGNED_ONLY                 when no recipients have usable key
    2.36 +//                                      and we are not forced to not sign the message,
    2.37 +//                                      a signed-only result is returned with this status 
    2.38  //      PEP_UNENCRYPTED                 on demand or no recipients with usable
    2.39  //                                      key, is left unencrypted, and key is
    2.40  //                                      attached to it
    2.41 +//      PEP_CANNOT_SIGN                 An attempt was made to sign-only and failed.
    2.42  //
    2.43  //  caveat:
    2.44  //      the ownership of src remains with the caller
     3.1 --- a/src/pEpEngine.h	Mon Sep 23 02:41:34 2019 +0200
     3.2 +++ b/src/pEpEngine.h	Mon Sep 23 14:56:17 2019 +0200
     3.3 @@ -84,7 +84,8 @@
     3.4      PEP_VERIFY_NO_KEY                               = 0x0407,
     3.5      PEP_VERIFIED_AND_TRUSTED                        = 0x0408,
     3.6      PEP_CANNOT_REENCRYPT                            = 0x0409,
     3.7 -    PEP_CANNOT_SIGN                                 = 0x040a,
     3.8 +    PEP_SIGNED_ONLY                                 = 0x040a,
     3.9 +    PEP_CANNOT_SIGN                                 = 0x040b,    
    3.10      PEP_CANNOT_DECRYPT_UNKNOWN                      = 0x04ff,
    3.11  
    3.12      PEP_TRUSTWORD_NOT_FOUND                         = 0x0501,
     4.1 --- a/test/src/Engine358Test.cc	Mon Sep 23 02:41:34 2019 +0200
     4.2 +++ b/test/src/Engine358Test.cc	Mon Sep 23 14:56:17 2019 +0200
     4.3 @@ -110,7 +110,8 @@
     4.4      message* enc_msg = NULL;
     4.5  
     4.6      status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
     4.7 -    ASSERT_EQ(enc_msg, nullptr);
     4.8 +    ASSERT_NE(enc_msg, nullptr);
     4.9      ASSERT_TRUE(msg->to && msg->to->ident);
    4.10 -    ASSERT_EQ(status , PEP_UNENCRYPTED);
    4.11 +    ASSERT_EQ(status , PEP_SIGNED_ONLY);
    4.12 +    ASSERT_EQ(enc_msg->enc_format, PEP_enc_sign_only);
    4.13  }
     5.1 --- a/test/src/ExternalRevokeTest.cc	Mon Sep 23 02:41:34 2019 +0200
     5.2 +++ b/test/src/ExternalRevokeTest.cc	Mon Sep 23 14:56:17 2019 +0200
     5.3 @@ -249,8 +249,9 @@
     5.4  
     5.5      status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
     5.6      output_stream << "Encryption returns with status " << tl_status_string(status) << endl;
     5.7 -    ASSERT_EQ(status, PEP_UNENCRYPTED);
     5.8 -    ASSERT_EQ(encrypted_outgoing_msg, nullptr);
     5.9 +    ASSERT_EQ(status, PEP_SIGNED_ONLY);
    5.10 +    ASSERT_NE(encrypted_outgoing_msg, nullptr);
    5.11 +    ASSERT_EQ(encrypted_outgoing_msg->enc_format, PEP_enc_sign_only);
    5.12      status = update_identity(session, recip1);
    5.13      ASSERT_EQ(recip1->comm_type, PEP_ct_key_not_found);
    5.14  
     6.1 --- a/test/src/KeyResetMessageTest.cc	Mon Sep 23 02:41:34 2019 +0200
     6.2 +++ b/test/src/KeyResetMessageTest.cc	Mon Sep 23 14:56:17 2019 +0200
     6.3 @@ -502,7 +502,8 @@
     6.4      message* enc_outgoing_msg = nullptr;
     6.5      output_stream << "Calling encrypt_message()\n";
     6.6      status = encrypt_message(session, outgoing_msg, NULL, &enc_outgoing_msg, PEP_enc_PGP_MIME, 0);
     6.7 -    ASSERT_EQ(status , PEP_UNENCRYPTED);
     6.8 +    ASSERT_EQ(status, PEP_SIGNED_ONLY);
     6.9 +    ASSERT_EQ(enc_outgoing_msg->enc_format, PEP_enc_sign_only);
    6.10      //
    6.11      output_stream << "Message created." << endl;
    6.12