src/pgp_netpgp.c
author Edouard Tisserant
Fri, 17 Apr 2015 11:29:01 +0200
changeset 208 0a01cff93e48
parent 207 b17a74f2acd9
child 209 8572f358fb61
permissions -rw-r--r--
netpgp : pgp_sign_and_fail_gracefully.
     1 #include "pEp_internal.h"
     2 #include "pgp_netpgp.h"
     3 
     4 #include <limits.h>
     5 
     6 #include "wrappers.h"
     7 
     8 #include <netpgp.h>
     9 #include <netpgp/config.h>
    10 #include <netpgp/memory.h>
    11 #include <netpgp/crypto.h>
    12 #include <netpgp/netpgpsdk.h>
    13 #include <netpgp/validate.h>
    14 
    15 #include <regex.h>
    16 
    17 #define PEP_NETPGP_DEBUG
    18 
    19 PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    20 {
    21     netpgp_t *netpgp;
    22     PEP_STATUS status = PEP_STATUS_OK;
    23     const char *home = NULL;
    24 
    25     assert(session);
    26     if(!session) return PEP_UNKNOWN_ERROR;
    27 
    28     netpgp = &session->ctx;
    29    
    30     if (in_first) {
    31         if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
    32             setlocale(LC_ALL, "");
    33     }
    34 
    35     memset(netpgp, 0x0, sizeof(session->ctx));
    36 
    37     // netpgp_setvar(netpgp, "max mem alloc", "4194304");
    38     netpgp_setvar(netpgp, "need seckey", "1");
    39     netpgp_setvar(netpgp, "need userid", "1");
    40 
    41     // NetPGP shares home with GPG
    42     home = gpg_home();
    43     if(home){
    44         netpgp_set_homedir(netpgp,(char*)home, NULL, 0);
    45     }else{
    46         status = PEP_INIT_NO_GPG_HOME;
    47         goto pep_error;
    48     }
    49 
    50     // pair with gpg's cert-digest-algo
    51     netpgp_setvar(netpgp, "hash", "SHA256");
    52 
    53     // subset of gpg's personal-cipher-preferences
    54     // here only one cipher can be selected
    55     netpgp_setvar(netpgp, "cipher", "AES256");
    56 
    57     if (!netpgp_init(netpgp)) {
    58         status = PEP_INIT_NETPGP_INIT_FAILED;
    59         goto pep_error;
    60     }
    61 
    62     return PEP_STATUS_OK;
    63 
    64 pep_error:
    65     pgp_release(session, in_first);
    66     return status;
    67 }
    68 
    69 void pgp_release(PEP_SESSION session, bool out_last)
    70 {
    71     netpgp_t *netpgp;
    72 
    73     assert(session);
    74     if(!session) return;
    75 
    76     netpgp = &session->ctx;
    77 
    78     netpgp_end(netpgp);
    79     memset(netpgp, 0x0, sizeof(session->ctx));
    80 
    81     // out_last unused here
    82 }
    83 
    84 // return 1 if the file contains ascii-armoured text 
    85 // buf MUST be \0 terminated to be checked for armour
    86 static unsigned
    87 _armoured(const char *buf, size_t size, const char *pattern)
    88 {
    89     unsigned armoured = 0;
    90     if(buf[size]=='\0'){
    91         regex_t r;
    92         regcomp(&r, pattern, REG_EXTENDED|REG_NEWLINE|REG_NOSUB);
    93         if (regexec(&r, buf, 0, NULL, 0) == 0) {
    94             armoured = 1;
    95         }
    96         regfree(&r);
    97     }
    98     return armoured;
    99 }
   100 
   101 // Iterate through netpgp' reported valid signatures 
   102 // fill a list of valid figerprints
   103 // returns PEP_STATUS_OK if all sig reported valid
   104 // error status otherwise.
   105 static PEP_STATUS _validation_results(netpgp_t *netpgp, pgp_validation_t *vresult,
   106                                              stringlist_t **_keylist)
   107 {
   108     time_t    now;
   109     time_t    t;
   110     char    buf[128];
   111 
   112     now = time(NULL);
   113     if (now < vresult->birthtime) {
   114         // signature is not valid yet
   115 #ifdef PEP_NETPGP_DEBUG
   116         (void) printf(
   117             "signature not valid until %.24s\n",
   118             ctime(&vresult->birthtime));
   119 #endif //PEP_NETPGP_DEBUG
   120         return PEP_UNENCRYPTED;
   121     }
   122     if (vresult->duration != 0 && now > vresult->birthtime + vresult->duration) {
   123         // signature has expired
   124         t = vresult->duration + vresult->birthtime;
   125 #ifdef PEP_NETPGP_DEBUG
   126         (void) printf(
   127             "signature not valid after %.24s\n",
   128             ctime(&t));
   129 #endif //PEP_NETPGP_DEBUG
   130         return PEP_UNENCRYPTED;
   131     }
   132     if (vresult->validc && vresult->valid_sigs &&
   133         !vresult->invalidc && !vresult->unknownc ) {
   134         unsigned    n;
   135         stringlist_t *k;
   136         // caller responsible to free
   137         *_keylist = new_stringlist(NULL);
   138         assert(*_keylist);
   139         if (*_keylist == NULL) {
   140             return PEP_OUT_OF_MEMORY;
   141         }
   142         k = *_keylist;
   143         for (n = 0; n < vresult->validc; ++n) {
   144             int i;
   145             char id[MAX_ID_LENGTH + 1];
   146             static const char *hexes = "0123456789abcdef";
   147             const uint8_t *userid = vresult->valid_sigs[n].signer_id;
   148 
   149 #ifdef PEP_NETPGP_DEBUG
   150             const pgp_key_t *key;
   151             pgp_pubkey_t *sigkey;
   152             unsigned from = 0;
   153             key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
   154                 (const uint8_t *) vresult->valid_sigs[n].signer_id,
   155                 &from, &sigkey);
   156             pgp_print_keydata(netpgp->io, netpgp->pubring, key, "valid signature ", &key->key.pubkey, 0);
   157 #endif //PEP_NETPGP_DEBUG
   158 
   159             for (i = 0; i < 8 ; i++) {
   160                 id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
   161                 id[(i * 2) + 1] = hexes[userid[i] & 0xf];
   162             }
   163             id[8 * 2] = 0x0;
   164 
   165             k = stringlist_add(k, id);
   166             if(!k){
   167                 free_stringlist(*_keylist);
   168                 return PEP_OUT_OF_MEMORY;
   169             }
   170         }
   171         return PEP_STATUS_OK;
   172     }
   173     if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
   174         // No signatures found - is this memory signed?
   175         return PEP_VERIFY_NO_KEY; 
   176     } 
   177     
   178     if (vresult->invalidc) {
   179         // some invalid signatures
   180 
   181 #ifdef PEP_NETPGP_DEBUG
   182         unsigned    n;
   183         for (n = 0; n < vresult->invalidc; ++n) {
   184             const pgp_key_t *key;
   185             pgp_pubkey_t *sigkey;
   186             unsigned from = 0;
   187             key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
   188                 (const uint8_t *) vresult->invalid_sigs[n].signer_id,
   189                 &from, &sigkey);
   190             pgp_print_keydata(netpgp->io, netpgp->pubring, key, "invalid signature ", &key->key.pubkey, 0);
   191             if (sigkey->duration != 0 && now > sigkey->birthtime + sigkey->duration) {
   192                 printf("EXPIRED !\n");
   193             }
   194         }
   195 #endif //PEP_NETPGP_DEBUG
   196 
   197         return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
   198     }
   199     
   200     // only unknown sigs
   201     return PEP_DECRYPT_WRONG_FORMAT;
   202 }
   203 
   204 #define ARMOR_HEAD    "^-----BEGIN PGP MESSAGE-----\\s*$"
   205 PEP_STATUS pgp_decrypt_and_verify(
   206     PEP_SESSION session, const char *ctext, size_t csize,
   207     char **ptext, size_t *psize, stringlist_t **keylist
   208     )
   209 {
   210     netpgp_t *netpgp;
   211     pgp_memory_t *mem;
   212     pgp_memory_t *cat;
   213     pgp_validation_t *vresult;
   214     char *_ptext = NULL;
   215     size_t _psize = 0;
   216     int ret;
   217 
   218     PEP_STATUS result;
   219     stringlist_t *_keylist = NULL;
   220     int i_key = 0;
   221 
   222     assert(session);
   223     assert(ctext);
   224     assert(csize);
   225     assert(ptext);
   226     assert(psize);
   227     assert(keylist);
   228 
   229     if(!session || !ctext || !csize || !ptext || !psize || !keylist) 
   230         return PEP_UNKNOWN_ERROR;
   231 
   232     netpgp = &session->ctx;
   233 
   234     *ptext = NULL;
   235     *psize = 0;
   236     *keylist = NULL;
   237 
   238     vresult = malloc(sizeof(pgp_validation_t));
   239     memset(vresult, 0x0, sizeof(pgp_validation_t));
   240 
   241     mem = pgp_decrypt_and_validate_buf(netpgp->io, vresult, ctext, csize,
   242                 netpgp->secring, netpgp->pubring,
   243                 _armoured(ctext, csize, ARMOR_HEAD),
   244                 0 /* sshkeys */,
   245                 NULL, -1, NULL  /* pass fp,attempts,cb */);
   246     if (mem == NULL) {
   247         return PEP_OUT_OF_MEMORY;
   248     }
   249 
   250     _psize = pgp_mem_len(mem);
   251     if (_psize){
   252         if ((_ptext = calloc(1, _psize)) == NULL) {
   253             result = PEP_OUT_OF_MEMORY;
   254             goto free_pgp;
   255         }
   256         memcpy(_ptext, pgp_mem_data(mem), _psize);
   257         result = PEP_DECRYPTED;
   258     }else{
   259         result = PEP_DECRYPT_NO_KEY;
   260         goto free_pgp;
   261     }
   262 
   263     if (result == PEP_DECRYPTED) {
   264         result = _validation_results(netpgp, vresult, &_keylist);
   265         if (result != PEP_STATUS_OK) {
   266             goto free_ptext;
   267         }
   268         result = PEP_DECRYPTED_AND_VERIFIED;
   269     }
   270 
   271     if (result == PEP_DECRYPTED_AND_VERIFIED
   272         || result == PEP_DECRYPTED) {
   273         *ptext = _ptext;
   274         *psize = _psize;
   275         (*ptext)[*psize] = 0; // safeguard for naive users
   276         if (result == PEP_DECRYPTED_AND_VERIFIED) {
   277             *keylist = _keylist;
   278         }
   279 
   280         /* _ptext and _keylist ownership transfer, don't free */
   281         goto free_pgp;
   282     }
   283 
   284 free_keylist:
   285     free_stringlist(_keylist);
   286 
   287 free_ptext:
   288     free(_ptext);
   289 
   290 free_pgp:
   291     pgp_memory_free(mem);
   292     pgp_validate_result_free(vresult);
   293 
   294     return result;
   295 }
   296 
   297 #define ARMOR_SIG_HEAD    "^-----BEGIN PGP (SIGNATURE|SIGNED MESSAGE)-----\\s*$"
   298 PEP_STATUS pgp_verify_text(
   299     PEP_SESSION session, const char *text, size_t size,
   300     const char *signature, size_t sig_size, stringlist_t **keylist
   301     )
   302 {
   303     netpgp_t *netpgp;
   304     pgp_memory_t *signedmem;
   305     pgp_memory_t *sig;
   306     pgp_validation_t *vresult;
   307 
   308     PEP_STATUS result;
   309     stringlist_t *_keylist;
   310 
   311     assert(session);
   312     assert(text);
   313     assert(size);
   314     assert(signature);
   315     assert(sig_size);
   316     assert(keylist);
   317 
   318     if(!session || !text || !size || !signature || !sig_size || !keylist) 
   319         return PEP_UNKNOWN_ERROR;
   320 
   321     netpgp = &session->ctx;
   322 
   323     *keylist = NULL;
   324 
   325     vresult = malloc(sizeof(pgp_validation_t));
   326     memset(vresult, 0x0, sizeof(pgp_validation_t));
   327 
   328     signedmem = pgp_memory_new();
   329     if (signedmem == NULL) {
   330         return PEP_OUT_OF_MEMORY;
   331     }
   332     pgp_memory_add(signedmem, (const uint8_t*)text, size);
   333 
   334     sig = pgp_memory_new();
   335     if (sig == NULL) {
   336         pgp_memory_free(signedmem);
   337         return PEP_OUT_OF_MEMORY;
   338     }
   339     pgp_memory_add(sig, (const uint8_t*)signature, sig_size);
   340 
   341     pgp_validate_mem_detached(netpgp->io, vresult, sig,
   342                 NULL,/* output */
   343                 _armoured(signature, sig_size, ARMOR_SIG_HEAD),
   344                 netpgp->pubring,
   345                 signedmem);
   346 
   347     result = _validation_results(netpgp, vresult, &_keylist);
   348     if (result != PEP_STATUS_OK) {
   349         goto free_pgp;
   350     }else{
   351         result = PEP_VERIFIED;
   352     }
   353 
   354     if (result == PEP_VERIFIED) {
   355         /* TODO : check trust level */
   356         result = PEP_VERIFIED_AND_TRUSTED;
   357     }
   358 
   359     if (result == PEP_VERIFIED || result == PEP_VERIFIED_AND_TRUSTED) {
   360         *keylist = _keylist;
   361 
   362         /* _keylist ownership transfer, don't free */
   363         goto free_pgp;
   364     }
   365 
   366 free_keylist:
   367     free_stringlist(_keylist);
   368 
   369 free_pgp:
   370     // free done by pgp_validate_mem_detached
   371     // pgp_memory_free(sig);
   372     // pgp_memory_free(signedmem);
   373     pgp_validate_result_free(vresult);
   374 
   375     return result;
   376 }
   377 
   378 PEP_STATUS pgp_encrypt_and_sign(
   379     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   380     size_t psize, char **ctext, size_t *csize
   381     )
   382 {
   383     netpgp_t *netpgp;
   384     const pgp_key_t *keypair;
   385     pgp_seckey_t *seckey;
   386 	pgp_memory_t *signedmem;
   387     const char *userid;
   388     const char *hashalg;
   389 
   390     PEP_STATUS result;
   391     const stringlist_t *_keylist;
   392     int i;
   393 
   394     assert(session);
   395     assert(keylist);
   396     assert(ptext);
   397     assert(psize);
   398     assert(ctext);
   399     assert(csize);
   400 
   401     if(!session || !ptext || !psize || !ctext || !csize || !keylist) 
   402         return PEP_UNKNOWN_ERROR;
   403 
   404     netpgp = &session->ctx;
   405 
   406     *ctext = NULL;
   407     *csize = 0;
   408 
   409     // Get signing details from netpgp
   410     if ((userid = netpgp_getvar(netpgp, "userid")) == NULL || 
   411         (keypair = pgp_getkeybyname(netpgp->io, netpgp->secring, userid)) == NULL ||
   412         (seckey = pgp_decrypt_seckey(keypair, NULL /*passfp*/)) == NULL) {
   413         return PEP_UNKNOWN_ERROR;
   414     }
   415     hashalg = netpgp_getvar(netpgp, "hash");
   416     if (seckey->pubkey.alg == PGP_PKA_DSA) {
   417     	hashalg = "sha1";
   418     }
   419 
   420     // Sign data
   421     signedmem = pgp_sign_buf(netpgp->io, ptext, psize, seckey,
   422     			time(NULL), /* birthtime */
   423     			0 /* duration */,
   424     			hashalg, 
   425                 0 /* armored */,
   426                 0 /* cleartext */);
   427 
   428     pgp_forget(seckey, (unsigned)sizeof(*seckey));
   429 
   430     if (!signedmem) {
   431         return PEP_UNENCRYPTED;
   432     }
   433 
   434     // Encrypt signed data
   435     pgp_memory_free(signedmem);
   436     result = PEP_UNKNOWN_ERROR;
   437     return result;
   438 /*
   439  *
   440  *
   441  *
   442  *
   443  *
   444  *
   445  *
   446  *
   447  *
   448  *
   449  * */
   450     for (_keylist = keylist, i = 0; _keylist != NULL; _keylist = _keylist->next, i++) {
   451         assert(_keylist->value);
   452         /* TODO */
   453         /* get key from  _keylist->value */
   454         /* add key to recipients/signers */
   455     }
   456 
   457     /* Do encrypt and sign */ 
   458     char *_buffer = NULL;
   459     size_t length = /* TODO length*/ 0;
   460     assert(length != -1);
   461 
   462     /* Allocate transferable buffer */
   463     _buffer = malloc(length + 1);
   464     assert(_buffer);
   465     if (_buffer == NULL) {
   466         /* TODO clean */
   467         return PEP_OUT_OF_MEMORY;
   468     }
   469 
   470     *ctext = _buffer;
   471     *csize = length;
   472     (*ctext)[*csize] = 0; // safeguard for naive users
   473     result = PEP_STATUS_OK;
   474 
   475     
   476     result = PEP_UNKNOWN_ERROR;
   477     return result;
   478 }
   479 
   480 PEP_STATUS pgp_generate_keypair(
   481     PEP_SESSION session, pEp_identity *identity
   482     )
   483 {
   484     char *parms;
   485     const char *template =
   486         "Key-Type: RSA\n"
   487         "Key-Length: 4096\n"
   488         "Name-Real: %s\n"
   489         "Name-Email: %s\n"
   490         /* "Passphrase: %s\n" */
   491         "Expire-Date: 1y\n";
   492     int result;
   493 
   494     assert(session);
   495     assert(identity);
   496     assert(identity->address);
   497     assert(identity->fpr == NULL);
   498     assert(identity->username);
   499 
   500     parms = calloc(1, PARMS_MAX);
   501     assert(parms);
   502     if (parms == NULL)
   503         return PEP_OUT_OF_MEMORY;
   504 
   505     result = snprintf(parms, PARMS_MAX, template, identity->username,
   506         identity->address);
   507     assert(result < PARMS_MAX);
   508     if (result >= PARMS_MAX) {
   509         free(parms);
   510         return PEP_BUFFER_TOO_SMALL;
   511     }
   512 
   513     /* TODO generate key */
   514 
   515     free(parms);
   516 
   517         return PEP_UNKNOWN_ERROR;
   518         return PEP_ILLEGAL_VALUE;
   519         return PEP_CANNOT_CREATE_KEY;
   520 
   521     identity->fpr = strdup("TODO generated key fpr");
   522 
   523     return PEP_STATUS_OK;
   524 }
   525 
   526 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
   527 {
   528     assert(session);
   529     assert(fpr);
   530 
   531     /* TODO get key with given fpr */
   532         return PEP_KEY_NOT_FOUND;
   533         return PEP_ILLEGAL_VALUE;
   534         return PEP_KEY_HAS_AMBIG_NAME;
   535         return PEP_OUT_OF_MEMORY;
   536         return PEP_UNKNOWN_ERROR;
   537 
   538     /* TODO delete that key */
   539         return PEP_UNKNOWN_ERROR;
   540         return PEP_KEY_NOT_FOUND;
   541         return PEP_KEY_HAS_AMBIG_NAME;
   542         return PEP_UNKNOWN_ERROR;
   543 
   544     return PEP_STATUS_OK;
   545 }
   546 
   547 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
   548 {
   549     assert(session);
   550     assert(key_data);
   551 
   552     /* TODO import */
   553         return PEP_UNKNOWN_ERROR;
   554         return PEP_ILLEGAL_VALUE;
   555         return PEP_UNKNOWN_ERROR;
   556     return PEP_STATUS_OK;
   557 }
   558 
   559 PEP_STATUS pgp_export_keydata(
   560     PEP_SESSION session, const char *fpr, char **key_data, size_t *size
   561     )
   562 {
   563     size_t _size;
   564     char *buffer;
   565     int reading;
   566 
   567     assert(session);
   568     assert(fpr);
   569     assert(key_data);
   570     assert(size);
   571 
   572 
   573     /* TODO export */
   574         return PEP_KEY_NOT_FOUND;
   575         return PEP_UNKNOWN_ERROR;
   576         return PEP_UNKNOWN_ERROR;
   577 
   578     _size = /* TODO */ 0;
   579     assert(_size != -1);
   580 
   581     buffer = malloc(_size + 1);
   582     assert(buffer);
   583     if (buffer == NULL) {
   584         /* TODO clean */
   585         return PEP_OUT_OF_MEMORY;
   586     }
   587 
   588     // safeguard for the naive user
   589     buffer[_size] = 0;
   590 
   591     *key_data = buffer;
   592     *size = _size;
   593 
   594     return PEP_STATUS_OK;
   595 }
   596 
   597 // "keyserver"
   598 // "hkp://keys.gnupg.net"
   599 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
   600 {
   601     assert(session);
   602     assert(pattern);
   603 
   604     /* TODO ask for key */
   605         return PEP_UNKNOWN_ERROR;
   606         return PEP_GET_KEY_FAILED;
   607 
   608     do {
   609 
   610         /* For each key */
   611         /* import key */
   612     } while (0);
   613 
   614     return PEP_STATUS_OK;
   615 }
   616 
   617 PEP_STATUS pgp_find_keys(
   618     PEP_SESSION session, const char *pattern, stringlist_t **keylist
   619     )
   620 {
   621     stringlist_t *_keylist;
   622     char *fpr;
   623 
   624     assert(session);
   625     assert(pattern);
   626     assert(keylist);
   627 
   628     *keylist = NULL;
   629 
   630     /* Ask for key */
   631         return PEP_UNKNOWN_ERROR;
   632         return PEP_GET_KEY_FAILED;
   633 
   634     _keylist = new_stringlist(NULL);
   635     stringlist_t *_k = _keylist;
   636 
   637     do {
   638             fpr = "TODO key->subkeys->fpr";
   639             assert(fpr);
   640             _k = stringlist_add(_k, fpr);
   641             assert(_k);
   642             if (_k == NULL){
   643                 free_stringlist(_keylist);
   644                 return PEP_OUT_OF_MEMORY;
   645             }
   646     } while (0);
   647 
   648     *keylist = _keylist;
   649     return PEP_STATUS_OK;
   650 }
   651 
   652 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
   653 {
   654     assert(session);
   655     assert(pattern);
   656 
   657     /* TODO send key */
   658 
   659         return PEP_CANNOT_SEND_KEY;
   660         return PEP_STATUS_OK;
   661 }
   662 
   663 
   664 PEP_STATUS pgp_get_key_rating(
   665     PEP_SESSION session,
   666     const char *fpr,
   667     PEP_comm_type *comm_type
   668     )
   669 {
   670     PEP_STATUS status = PEP_STATUS_OK;
   671 
   672     assert(session);
   673     assert(fpr);
   674     assert(comm_type);
   675 
   676     *comm_type = PEP_ct_unknown;
   677 
   678     /* TODO get key from fpr */
   679     return PEP_UNKNOWN_ERROR;
   680     return PEP_GET_KEY_FAILED;
   681 
   682     switch (/*TODO key->protocol*/ 4) {
   683     case /* TODO  OpenPGP */0:
   684     case /* TODO DEFAULT */1:
   685         *comm_type = PEP_ct_OpenPGP_unconfirmed;
   686         break;
   687     case /* TODO CMS */2:
   688         *comm_type = PEP_ct_CMS_unconfirmed;
   689         break;
   690     default:
   691         *comm_type = PEP_ct_unknown;
   692         return PEP_STATUS_OK;
   693     }
   694 
   695         for (; 1 == 0; /* Each subkeys */ ) {
   696             if (/* TODO length */0 < 1024)
   697                 *comm_type = PEP_ct_key_too_short;
   698             else if (
   699                 (
   700                 (   /* TODO pubkey_algo == RSA  */ 0)
   701                 || (/* TODO pubkey_algo == RSA_E*/ 0)
   702                 || (/* TODO pubkey_algo == RSA_S*/ 0)
   703                 )
   704                 && /* sk->length */0 == 1024
   705                 )
   706                 *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
   707 
   708             if (/* TODO invalid */ 1) {
   709                 *comm_type = PEP_ct_key_b0rken;
   710                 break;
   711             }
   712             if (/* TODO expired */ 1) {
   713                 *comm_type = PEP_ct_key_expired;
   714                 break;
   715             }
   716             if (/* TODO revoked*/ 1) {
   717                 *comm_type = PEP_ct_key_revoked;
   718                 break;
   719             }
   720         }
   721         *comm_type = PEP_ct_unknown;
   722         return PEP_OUT_OF_MEMORY;
   723         return PEP_UNKNOWN_ERROR;
   724 
   725 
   726     return status;
   727 }