src/pgp_netpgp.c
changeset 279 99e9815751fa
parent 277 5c8838004648
child 286 bac6a8feb1cf
     1.1 --- a/src/pgp_netpgp.c	Wed May 13 01:03:55 2015 +0200
     1.2 +++ b/src/pgp_netpgp.c	Sun May 17 00:58:43 2015 +0200
     1.3 @@ -219,8 +219,11 @@
     1.4  // fill a list of valid figerprints
     1.5  // returns PEP_STATUS_OK if all sig reported valid
     1.6  // error status otherwise.
     1.7 -static PEP_STATUS _validation_results(netpgp_t *netpgp, pgp_validation_t *vresult,
     1.8 -                                             stringlist_t **_keylist)
     1.9 +static PEP_STATUS _validation_results(
    1.10 +        netpgp_t *netpgp,
    1.11 +        pgp_validation_t *vresult,
    1.12 +        stringlist_t **_keylist
    1.13 +    )
    1.14  {
    1.15      time_t    now;
    1.16      time_t    t;
    1.17 @@ -500,7 +503,9 @@
    1.18  
    1.19      // Get signing details from netpgp
    1.20      if ((userid = netpgp_getvar(&netpgp, "userid")) == NULL || 
    1.21 -        (keypair = pgp_getkeybyname(netpgp.io, netpgp.secring, userid)) == NULL ||
    1.22 +        (keypair = pgp_getkeybyname(netpgp.io, 
    1.23 +                                    netpgp.secring, 
    1.24 +                                    userid)) == NULL ||
    1.25          (seckey = pgp_decrypt_seckey(keypair, NULL /*passfp*/)) == NULL) {
    1.26          return PEP_UNKNOWN_ERROR;
    1.27      }
    1.28 @@ -646,11 +651,12 @@
    1.29  }
    1.30  
    1.31  static PEP_STATUS import_key_or_keypair(netpgp_t *netpgp, pgp_key_t *newkey){
    1.32 -    pgp_key_t	pubkey;
    1.33 +    pgp_key_t pubkey;
    1.34      unsigned public;
    1.35      PEP_STATUS result;
    1.36 -    
    1.37 -    /* XXX TODO : check key is valid */
    1.38 +    pgp_keyring_t tmpring;
    1.39 +	pgp_validation_t *vresult;
    1.40 +
    1.41      /* XXX TODO : replace/update key if already in ring */
    1.42  
    1.43      if ((public = (newkey->type == PGP_PTAG_CT_PUBLIC_KEY))){
    1.44 @@ -663,6 +669,52 @@
    1.45          }
    1.46      }
    1.47  
    1.48 +    // Verify pubkey against a temporary keyring containing the key itself
    1.49 +    // (netpgp does check subkey binding sigs agains all the given ring,
    1.50 +    // and doesn't ensure signer is the primary key itself)
    1.51 +    bzero(&tmpring, sizeof(tmpring));
    1.52 +    if(!pgp_keyring_add(&tmpring, &pubkey)){
    1.53 +        result = PEP_OUT_OF_MEMORY;
    1.54 +        goto free_pubkey;
    1.55 +    }
    1.56 +
    1.57 +    vresult = malloc(sizeof(pgp_validation_t));
    1.58 +    memset(vresult, 0x0, sizeof(pgp_validation_t));
    1.59 +    pgp_validate_key_sigs(vresult, &pubkey, &tmpring, NULL);
    1.60 +    pgp_keyring_free(&tmpring);
    1.61 +    
    1.62 +    // There may be no single valid signature (not mandatory)
    1.63 +    // but at least there must be no invalid signature
    1.64 +    if (vresult->invalidc) {
    1.65 +        result = PEP_UNKNOWN_ERROR;
    1.66 +    } else {
    1.67 +
    1.68 +        // check key consistency by ensuring no subkey or 
    1.69 +        // direct signature are unknown
    1.70 +        unsigned    n;
    1.71 +        result = PEP_STATUS_OK;
    1.72 +        for (n = 0; n < vresult->unknownc && result == PEP_STATUS_OK; ++n) {
    1.73 +            switch (vresult->unknown_sigs[n].type) {
    1.74 +            case PGP_SIG_SUBKEY:
    1.75 +            case PGP_SIG_DIRECT:
    1.76 +	        case PGP_SIG_PRIMARY: /* TODO is ignored by netpgp XXX */
    1.77 +                result = PEP_UNKNOWN_ERROR;
    1.78 +                break;
    1.79 +            default:
    1.80 +                break;
    1.81 +            }
    1.82 +        }
    1.83 +        // TODO check in netpgp parser source that 
    1.84 +        // presence of a subkey binding signature
    1.85 +        // is enforced
    1.86 +    }
    1.87 +
    1.88 +    pgp_validate_result_free(vresult);
    1.89 +
    1.90 +    if (result != PEP_STATUS_OK) {
    1.91 +        if (!public) goto free_pubkey;
    1.92 +        return result;
    1.93 +    }
    1.94      // Append key to netpgp's rings (key ownership transfered)
    1.95      if (!public && !pgp_keyring_add(netpgp->secring, newkey)){
    1.96          result = PEP_OUT_OF_MEMORY;
    1.97 @@ -818,9 +870,12 @@
    1.98  }
    1.99  
   1.100  #define ARMOR_KEY_HEAD    "^-----BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK-----\\s*$"
   1.101 -PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
   1.102 +PEP_STATUS pgp_import_keydata(
   1.103 +        PEP_SESSION session,
   1.104 +        const char *key_data, 
   1.105 +        size_t size
   1.106 +    )
   1.107  {
   1.108 -
   1.109      pgp_memory_t *mem;
   1.110      pgp_keyring_t tmpring;
   1.111      unsigned i = 0;