src/pgp_netpgp.c
author Edouard Tisserant
Thu, 02 Apr 2015 16:03:54 +0200
changeset 175 59c8eabab690
parent 174 9c3d0eaa8ea1
child 179 112fadcf74b9
permissions -rw-r--r--
netpgp : build, link, init, release.
     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 PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    10 {
    11     PEP_STATUS status = PEP_STATUS_OK;
    12     const char *home = NULL;
    13    
    14     if (in_first) {
    15         if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
    16             setlocale(LC_ALL, "");
    17     }
    18 
    19 	memset(&session->ctx, 0x0, sizeof(session->ctx));
    20 
    21     // NetPGP shares home with GPG
    22     home = gpg_home();
    23     if(home){
    24         netpgp_set_homedir(&session->ctx,(char*)home, NULL, 0);
    25     }else{
    26         status = PEP_INIT_NO_GPG_HOME;
    27         goto pep_error;
    28     }
    29 
    30     // pair with gpg's cert-digest-algo
    31 	netpgp_setvar(&session->ctx, "hash", "SHA256");
    32 
    33     // subset of gpg's personal-cipher-preferences
    34     // here only one cipher can be selected
    35     netpgp_setvar(&session->ctx, "cipher", "AES256");
    36 
    37 	if (!netpgp_init(&session->ctx)) {
    38         status = PEP_INIT_NETPGP_INIT_FAILED;
    39         goto pep_error;
    40     }
    41 
    42     return PEP_STATUS_OK;
    43 
    44 pep_error:
    45     pgp_release(session, in_first);
    46     return status;
    47 }
    48 
    49 void pgp_release(PEP_SESSION session, bool out_last)
    50 {
    51 	netpgp_end(&session->ctx);
    52 	memset(&session->ctx, 0x0, sizeof(session->ctx));
    53 
    54     // out_last unused here
    55 }
    56 
    57 PEP_STATUS pgp_decrypt_and_verify(
    58     PEP_SESSION session, const char *ctext, size_t csize,
    59     char **ptext, size_t *psize, stringlist_t **keylist
    60     )
    61 {
    62     PEP_STATUS result;
    63 
    64     stringlist_t *_keylist = NULL;
    65     int i_key = 0;
    66 
    67     assert(session);
    68     assert(ctext);
    69     assert(csize);
    70     assert(ptext);
    71     assert(psize);
    72     assert(keylist);
    73 
    74     *ptext = NULL;
    75     *psize = 0;
    76     *keylist = NULL;
    77 
    78     /* TODO identify cipher text */
    79     /* if recognized */
    80     /* decrypt */
    81     /* if OK, verify */
    82     /*
    83     result = PEP_DECRYPTED_AND_VERIFIED;
    84     result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
    85     result = PEP_DECRYPTED;
    86     result = PEP_DECRYPT_WRONG_FORMAT;
    87     result = PEP_DECRYPT_NO_KEY;
    88     return PEP_OUT_OF_MEMORY;
    89     */
    90     result = PEP_UNKNOWN_ERROR;
    91                 stringlist_t *k;
    92                 _keylist = new_stringlist(NULL);
    93                 assert(_keylist);
    94                 if (_keylist == NULL) {
    95                     /* TODO */
    96                     return PEP_OUT_OF_MEMORY;
    97                 }
    98                 k = _keylist;
    99                 do {
   100                         k = stringlist_add(k, "SIGNATURE FPR"/*TODO*/);
   101                 } while (0 /* TODO sign next*/);
   102 
   103     return result;
   104 }
   105 
   106 PEP_STATUS pgp_verify_text(
   107     PEP_SESSION session, const char *text, size_t size,
   108     const char *signature, size_t sig_size, stringlist_t **keylist
   109     )
   110 {
   111     PEP_STATUS result;
   112     stringlist_t *_keylist;
   113 
   114     assert(session);
   115     assert(text);
   116     assert(size);
   117     assert(signature);
   118     assert(sig_size);
   119     assert(keylist);
   120 
   121     *keylist = NULL;
   122     /* if OK, verify */
   123             stringlist_t *k;
   124             k = _keylist;
   125             result = PEP_VERIFIED;
   126             do {
   127                 k = stringlist_add(k, "TODO");
   128                 if (k == NULL) {
   129                     free_stringlist(_keylist);
   130                     /* TODO */
   131                     return PEP_OUT_OF_MEMORY;
   132                 }
   133             } while (0 /*TODO*/);
   134             *keylist = _keylist;
   135     /*
   136     result = PEP_UNENCRYPTED;
   137     result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
   138     result = PEP_VERIFIED_AND_TRUSTED;
   139     result = PEP_VERIFY_NO_KEY;
   140     result = PEP_UNENCRYPTED;
   141     result = PEP_DECRYPT_WRONG_FORMAT;
   142     return PEP_OUT_OF_MEMORY;
   143     */
   144     result = PEP_UNKNOWN_ERROR;
   145 
   146     return result;
   147 }
   148 
   149 PEP_STATUS pgp_encrypt_and_sign(
   150     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   151     size_t psize, char **ctext, size_t *csize
   152     )
   153 {
   154     PEP_STATUS result;
   155     const stringlist_t *_keylist;
   156     int i, j;
   157 
   158     assert(session);
   159     assert(keylist);
   160     assert(ptext);
   161     assert(psize);
   162     assert(ctext);
   163     assert(csize);
   164 
   165     *ctext = NULL;
   166     *csize = 0;
   167 
   168     for (_keylist = keylist, i = 0; _keylist != NULL; _keylist = _keylist->next, i++) {
   169         assert(_keylist->value);
   170         /* TODO */
   171         /* get key from  _keylist->value */
   172         /* add key to recipients/signers */
   173     }
   174 
   175     /* Do encrypt and sign */ 
   176     char *_buffer = NULL;
   177     size_t length = /* TODO length*/ 0;
   178     assert(length != -1);
   179 
   180     /* Allocate transferable buffer */
   181     _buffer = malloc(length + 1);
   182     assert(_buffer);
   183     if (_buffer == NULL) {
   184         /* TODO clean */
   185         return PEP_OUT_OF_MEMORY;
   186     }
   187 
   188     *ctext = _buffer;
   189     *csize = length;
   190     (*ctext)[*csize] = 0; // safeguard for naive users
   191     result = PEP_STATUS_OK;
   192 
   193     
   194     result = PEP_UNKNOWN_ERROR;
   195     return result;
   196 }
   197 
   198 PEP_STATUS pgp_generate_keypair(
   199     PEP_SESSION session, pEp_identity *identity
   200     )
   201 {
   202     char *parms;
   203     const char *template =
   204         "Key-Type: RSA\n"
   205         "Key-Length: 4096\n"
   206         "Name-Real: %s\n"
   207         "Name-Email: %s\n"
   208         /* "Passphrase: %s\n" */
   209         "Expire-Date: 1y\n";
   210     int result;
   211 
   212     assert(session);
   213     assert(identity);
   214     assert(identity->address);
   215     assert(identity->fpr == NULL);
   216     assert(identity->username);
   217 
   218     parms = calloc(1, PARMS_MAX);
   219     assert(parms);
   220     if (parms == NULL)
   221         return PEP_OUT_OF_MEMORY;
   222 
   223     result = snprintf(parms, PARMS_MAX, template, identity->username,
   224         identity->address);
   225     assert(result < PARMS_MAX);
   226     if (result >= PARMS_MAX) {
   227         free(parms);
   228         return PEP_BUFFER_TOO_SMALL;
   229     }
   230 
   231     /* TODO generate key */
   232 
   233     free(parms);
   234 
   235         return PEP_UNKNOWN_ERROR;
   236         return PEP_ILLEGAL_VALUE;
   237         return PEP_CANNOT_CREATE_KEY;
   238 
   239     identity->fpr = strdup("TODO generated key fpr");
   240 
   241     return PEP_STATUS_OK;
   242 }
   243 
   244 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
   245 {
   246     assert(session);
   247     assert(fpr);
   248 
   249     /* TODO get key with given fpr */
   250         return PEP_KEY_NOT_FOUND;
   251         return PEP_ILLEGAL_VALUE;
   252         return PEP_KEY_HAS_AMBIG_NAME;
   253         return PEP_OUT_OF_MEMORY;
   254         return PEP_UNKNOWN_ERROR;
   255 
   256     /* TODO delete that key */
   257         return PEP_UNKNOWN_ERROR;
   258         return PEP_KEY_NOT_FOUND;
   259         return PEP_KEY_HAS_AMBIG_NAME;
   260         return PEP_UNKNOWN_ERROR;
   261 
   262     return PEP_STATUS_OK;
   263 }
   264 
   265 PEP_STATUS pgp_import_key(PEP_SESSION session, const char *key_data, size_t size)
   266 {
   267     assert(session);
   268     assert(key_data);
   269 
   270     /* TODO import */
   271         return PEP_UNKNOWN_ERROR;
   272         return PEP_ILLEGAL_VALUE;
   273         return PEP_UNKNOWN_ERROR;
   274     return PEP_STATUS_OK;
   275 }
   276 
   277 PEP_STATUS pgp_export_key(
   278     PEP_SESSION session, const char *fpr, char **key_data, size_t *size
   279     )
   280 {
   281     size_t _size;
   282     char *buffer;
   283     int reading;
   284 
   285     assert(session);
   286     assert(fpr);
   287     assert(key_data);
   288     assert(size);
   289 
   290 
   291     /* TODO export */
   292         return PEP_KEY_NOT_FOUND;
   293         return PEP_UNKNOWN_ERROR;
   294         return PEP_UNKNOWN_ERROR;
   295 
   296     _size = /* TODO */ 0;
   297     assert(_size != -1);
   298 
   299     buffer = malloc(_size + 1);
   300     assert(buffer);
   301     if (buffer == NULL) {
   302         /* TODO clean */
   303         return PEP_OUT_OF_MEMORY;
   304     }
   305 
   306     // safeguard for the naive user
   307     buffer[_size] = 0;
   308 
   309     *key_data = buffer;
   310     *size = _size;
   311 
   312     return PEP_STATUS_OK;
   313 }
   314 
   315 // "keyserver"
   316 // "hkp://keys.gnupg.net"
   317 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
   318 {
   319     assert(session);
   320     assert(pattern);
   321 
   322     /* TODO ask for key */
   323         return PEP_UNKNOWN_ERROR;
   324         return PEP_GET_KEY_FAILED;
   325 
   326     do {
   327 
   328         /* For each key */
   329         /* import key */
   330     } while (0);
   331 
   332     return PEP_STATUS_OK;
   333 }
   334 
   335 PEP_STATUS pgp_find_keys(
   336     PEP_SESSION session, const char *pattern, stringlist_t **keylist
   337     )
   338 {
   339     stringlist_t *_keylist;
   340     char *fpr;
   341 
   342     assert(session);
   343     assert(pattern);
   344     assert(keylist);
   345 
   346     *keylist = NULL;
   347 
   348     /* Ask for key */
   349         return PEP_UNKNOWN_ERROR;
   350         return PEP_GET_KEY_FAILED;
   351 
   352     _keylist = new_stringlist(NULL);
   353     stringlist_t *_k = _keylist;
   354 
   355     do {
   356             fpr = "TODO key->subkeys->fpr";
   357             assert(fpr);
   358             _k = stringlist_add(_k, fpr);
   359             assert(_k);
   360             if (_k == NULL){
   361                 free_stringlist(_keylist);
   362                 return PEP_OUT_OF_MEMORY;
   363             }
   364     } while (0);
   365 
   366     *keylist = _keylist;
   367     return PEP_STATUS_OK;
   368 }
   369 
   370 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
   371 {
   372     assert(session);
   373     assert(pattern);
   374 
   375     /* TODO send key */
   376 
   377         return PEP_CANNOT_SEND_KEY;
   378         return PEP_STATUS_OK;
   379 }
   380 
   381 
   382 PEP_STATUS pgp_get_key_rating(
   383     PEP_SESSION session,
   384     const char *fpr,
   385     PEP_comm_type *comm_type
   386     )
   387 {
   388     PEP_STATUS status = PEP_STATUS_OK;
   389 
   390     assert(session);
   391     assert(fpr);
   392     assert(comm_type);
   393 
   394     *comm_type = PEP_ct_unknown;
   395 
   396     /* TODO get key from fpr */
   397     return PEP_UNKNOWN_ERROR;
   398     return PEP_GET_KEY_FAILED;
   399 
   400     switch (/*TODO key->protocol*/ 4) {
   401     case /* TODO  OpenPGP */0:
   402     case /* TODO DEFAULT */1:
   403         *comm_type = PEP_ct_OpenPGP_unconfirmed;
   404         break;
   405     case /* TODO CMS */2:
   406         *comm_type = PEP_ct_CMS_unconfirmed;
   407         break;
   408     default:
   409         *comm_type = PEP_ct_unknown;
   410         return PEP_STATUS_OK;
   411     }
   412 
   413         for (; 1 == 0; /* Each subkeys */ ) {
   414             if (/* TODO length */0 < 1024)
   415                 *comm_type = PEP_ct_key_too_short;
   416             else if (
   417                 (
   418                 (   /* TODO pubkey_algo == RSA  */ 0)
   419                 || (/* TODO pubkey_algo == RSA_E*/ 0)
   420                 || (/* TODO pubkey_algo == RSA_S*/ 0)
   421                 )
   422                 && /* sk->length */0 == 1024
   423                 )
   424                 *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
   425 
   426             if (/* TODO invalid */ 1) {
   427                 *comm_type = PEP_ct_key_b0rken;
   428                 break;
   429             }
   430             if (/* TODO expired */ 1) {
   431                 *comm_type = PEP_ct_key_expired;
   432                 break;
   433             }
   434             if (/* TODO revoked*/ 1) {
   435                 *comm_type = PEP_ct_key_revoked;
   436                 break;
   437             }
   438         }
   439         *comm_type = PEP_ct_unknown;
   440         return PEP_OUT_OF_MEMORY;
   441         return PEP_UNKNOWN_ERROR;
   442 
   443 
   444     return status;
   445 }