Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

JEncryption.c

Go to the documentation of this file.
00001 /* $Id: JEncryption.c,v 1.9 2004/02/24 04:20:08 jadestorm Exp $ */
00002 
00003 #include <sysdep.h>
00004 #include "include/libjwgc.h"
00005 #ifdef USE_GPGME
00006 #include <gpgme.h>
00007 
00008 xode *key_list = NULL;
00009 int num_keys = 0;
00010 
00011 static void
00012 print_op_info (GpgmeCtx c)
00013 {
00014         char *s = gpgme_get_op_info (c, 0);
00015 
00016         if (!s) {
00017                 dprintf(dGPG, "<!-- no operation info available -->");
00018         }
00019         else {
00020                 dprintf(dGPG, "%s", s);
00021                 free (s);
00022         }
00023 }
00024 
00025 static const char *
00026 passphrase_cb (void *opaque, const char *desc, void **r_hd)
00027 {
00028         const char *pass;
00029 
00030         if (!desc) {
00031                 return NULL;
00032         }
00033 
00034         pass = (char *)jVars_get(jVarGPGPass);
00035         return pass;
00036 }
00037 
00038 char *
00039 JSign(char *data)
00040 {
00041         GpgmeCtx ctx;
00042         GpgmeError err;
00043         GpgmeData in, out;
00044         char *retdata;
00045         char buf[100];
00046         size_t nread;
00047         size_t retsz;
00048 
00049         retdata = (char *)malloc(sizeof(char) * 1);
00050         retdata[0] = '\0';
00051         retsz = 0;
00052 
00053         err = gpgme_new(&ctx);
00054         if (err) {
00055                 dprintf(dGPG, "Failed to create GPGME context.\n");
00056                 return NULL;
00057         }
00058 
00059         gpgme_set_passphrase_cb(ctx, passphrase_cb, NULL);
00060         gpgme_set_textmode(ctx, 1);
00061         gpgme_set_armor(ctx, 1);
00062 
00063         err = gpgme_data_new_from_mem(&in, data, strlen(data), 0);
00064         if (err) {
00065                 dprintf(dGPG, "Failed to create input data.\n");
00066                 return NULL;
00067         }
00068 
00069         err = gpgme_data_new(&out);
00070         if (err) {
00071                 dprintf(dGPG, "Failed to create output data.\n");
00072                 return NULL;
00073         }
00074 
00075         err = gpgme_op_sign(ctx, in, out, GPGME_SIG_MODE_DETACH);
00076         if (err) {
00077                 dprintf(dGPG, "Detached signature failed.\n");
00078                 return NULL;
00079         }
00080 
00081         fflush(NULL);
00082         print_op_info(ctx);
00083 
00084         err = gpgme_data_rewind(out);
00085         if (err) {
00086                 dprintf(dGPG, "Failed to rewind data stream.\n");
00087                 return NULL;
00088         }
00089         while (!(err = gpgme_data_read(out, buf, 100, &nread))) {
00090                 retsz += nread;
00091                 retdata = realloc(retdata, sizeof(char) * (retsz + 1));
00092                 strcat(retdata, buf);
00093                 retdata[retsz] = '\0';
00094         }
00095 
00096         gpgme_data_release(out);
00097         gpgme_data_release(in);
00098         gpgme_release(ctx);
00099 
00100         dprintf(dGPG, "Successfully signed data:\n%s\n", retdata);
00101 
00102         return retdata;
00103 }
00104 
00105 char *
00106 JTrimPGPMessage(char *msg)
00107 {
00108         char *retstr, *cp, *tmpbuf;
00109 
00110         if (!msg) {
00111                 dprintf(dGPG, "Trimming empty string.\n");
00112                 return NULL;
00113         }
00114 
00115         dprintf(dGPG, "Trimming:\n%s\n", msg);
00116 
00117         retstr = (char *)malloc(sizeof(char) * 1);
00118         retstr[0] = '\0';
00119         tmpbuf = strdup(msg);
00120 
00121         cp = tmpbuf;
00122         cp = strtok(cp, "\n");
00123         dprintf(dGPG, "Searching for BEGIN...\n", cp);
00124         while (cp && strncmp(cp, "-----BEGIN", 10)) {
00125                 dprintf(dGPG, "Skipping %s\n", cp);
00126                 cp = strtok(NULL, "\n");
00127         }
00128         if (!cp) { return NULL; }
00129         dprintf(dGPG, "Skipping %s\n", cp);
00130         cp = strtok(NULL, "\n");
00131         dprintf(dGPG, "Searching for end of headers...\n", cp);
00132         while (cp && !strchr(cp, ' ')) {
00133                 dprintf(dGPG, "Skipping %s\n", cp);
00134                 cp = strtok(NULL, "\n");
00135         }
00136         if (!cp) { return NULL; }
00137         dprintf(dGPG, "Skipping %s\n", cp);
00138         cp = strtok(NULL, "\n");
00139         dprintf(dGPG, "Collecting all until END...\n", cp);
00140         while (cp && strncmp(cp, "-----END", 8)) {
00141                 dprintf(dGPG, "Keeping %s\n", cp);
00142                 retstr = realloc(retstr, sizeof(char) * (strlen(retstr) +
00143                                         strlen(cp) + 2));
00144                 strcat(retstr, cp);
00145                 strcat(retstr, "\n");
00146                 cp = strtok(NULL, "\n");
00147         }
00148         dprintf(dGPG, "Trimmed string is:\n%s\n", retstr);
00149 
00150         return retstr;
00151 }
00152 
00153 char *
00154 JDecrypt(char *data)
00155 {
00156         GpgmeCtx ctx;
00157         GpgmeError err;
00158         GpgmeData in, out;
00159         char *retdata;
00160         char *bufdata;
00161         char buf[100];
00162         size_t nread;
00163         size_t retsz;
00164 
00165         retdata = (char *)malloc(sizeof(char) * 1);
00166         retdata[0] = '\0';
00167         retsz = 0;
00168 
00169         err = gpgme_new(&ctx);
00170         if (err) {
00171                 dprintf(dGPG, "Failed to create GPGME context.\n");
00172                 return NULL;
00173         }
00174 
00175         gpgme_set_passphrase_cb(ctx, passphrase_cb, NULL);
00176         gpgme_set_textmode(ctx, 1);
00177         gpgme_set_armor(ctx, 1);
00178 
00179         bufdata = (char *)malloc(sizeof(char) * (strlen(data) + 1 + 68));
00180         sprintf(bufdata, "-----BEGIN PGP MESSAGE-----\nVersion: JWGC\n\n%s\n-----END PGP MESSAGE-----\n", data);
00181         dprintf(dGPG, "Parsing input data:\n%s\n", bufdata);
00182         err = gpgme_data_new_from_mem(&in, bufdata, strlen(bufdata), 0);
00183         if (err) {
00184                 dprintf(dGPG, "Failed to create input data.\n");
00185                 return NULL;
00186         }
00187 
00188         err = gpgme_data_new(&out);
00189         if (err) {
00190                 dprintf(dGPG, "Failed to create output data.\n");
00191                 return NULL;
00192         }
00193 
00194         err = gpgme_op_decrypt(ctx, in, out);
00195         if (err) {
00196                 dprintf(dGPG, "Data decryption failed.\n");
00197                 return NULL;
00198         }
00199 
00200         fflush(NULL);
00201 
00202         err = gpgme_data_rewind(out);
00203         if (err) {
00204                 dprintf(dGPG, "Failed to rewind data stream.\n");
00205                 return NULL;
00206         }
00207         while (!(err = gpgme_data_read(out, buf, 100, &nread))) {
00208                 retsz += nread;
00209                 retdata = realloc(retdata, sizeof(char) * (retsz + 1));
00210                 strcat(retdata, buf);
00211                 retdata[retsz] = '\0';
00212         }
00213 
00214         gpgme_data_release(out);
00215         gpgme_data_release(in);
00216         gpgme_release(ctx);
00217 
00218         dprintf(dGPG, "Successfully decrypted data:\n%s\n", retdata);
00219 
00220         return retdata;
00221 }
00222 
00223 char *
00224 JEncrypt(char *data, char *recipient)
00225 {
00226         GpgmeCtx ctx;
00227         GpgmeError err;
00228         GpgmeData in, out;
00229         GpgmeRecipients rset;
00230         char *retdata;
00231         char *bufdata;
00232         char buf[100];
00233         size_t nread;
00234         size_t retsz;
00235 
00236         retdata = (char *)malloc(sizeof(char) * 1);
00237         retdata[0] = '\0';
00238         retsz = 0;
00239 
00240         err = gpgme_check_engine();
00241         if (err) {
00242                 dprintf(dGPG, "Failed to check GPG engine.\n");
00243                 return NULL;
00244         }
00245         dprintf(dGPG, "Engine Info:\n%s\n", gpgme_get_engine_info());
00246 
00247         err = gpgme_new(&ctx);
00248         if (err) {
00249                 dprintf(dGPG, "Failed to create GPGME context.\n");
00250                 return NULL;
00251         }
00252 
00253         gpgme_set_armor(ctx, 1);
00254 
00255         err = gpgme_data_new_from_mem(&in, data, strlen(data), 0);
00256         if (err) {
00257                 dprintf(dGPG, "Failed to create input data.\n");
00258                 return NULL;
00259         }
00260 
00261         err = gpgme_data_new(&out);
00262         if (err) {
00263                 dprintf(dGPG, "Failed to create output data.\n");
00264                 return NULL;
00265         }
00266 
00267         err = gpgme_recipients_new(&rset);
00268         if (err) {
00269                 dprintf(dGPG, "Failed to initialize recipients.\n");
00270                 return NULL;
00271         }
00272 
00273         err = gpgme_recipients_add_name_with_validity(rset, recipient,
00274                                         GPGME_VALIDITY_FULL);
00275         if (err) {
00276                 dprintf(dGPG, "Failed to add recipient.\n");
00277                 return NULL;
00278         }
00279 
00280         err = gpgme_op_encrypt(ctx, rset, in, out);
00281         if (err) {
00282                 dprintf(dGPG, "Data encryption failed.\n");
00283                 return NULL;
00284         }
00285 
00286         print_op_info(ctx);
00287         fflush(NULL);
00288 
00289         err = gpgme_data_rewind(out);
00290         if (err) {
00291                 dprintf(dGPG, "Failed to rewind data stream.\n");
00292                 return NULL;
00293         }
00294         while (!(err = gpgme_data_read(out, buf, 100, &nread))) {
00295                 retsz += nread;
00296                 retdata = realloc(retdata, sizeof(char) * (retsz + 1));
00297                 strcat(retdata, buf);
00298                 retdata[retsz] = '\0';
00299         }
00300 
00301         gpgme_recipients_release(rset);
00302         gpgme_data_release(out);
00303         gpgme_data_release(in);
00304         gpgme_release(ctx);
00305 
00306         dprintf(dGPG, "Successfully encrypted data:\n%s\n", retdata);
00307 
00308         return retdata;
00309 }
00310 
00311 static const char *
00312 status_string(GpgmeSigStat status)
00313 {
00314         const char *s = "?";
00315 
00316         switch (status) {
00317                 case GPGME_SIG_STAT_NONE:
00318                         s = "None";
00319                         break;
00320 
00321                 case GPGME_SIG_STAT_NOSIG:
00322                         s = "No Signature";
00323                         break;
00324 
00325                 case GPGME_SIG_STAT_GOOD:
00326                         s = "Good";
00327                         break;
00328 
00329                 case GPGME_SIG_STAT_GOOD_EXP:
00330                         s = "Good but expired";
00331                         break;
00332 
00333                 case GPGME_SIG_STAT_GOOD_EXPKEY:
00334                         s = "Good but key exipired";
00335                         break;
00336 
00337                 case GPGME_SIG_STAT_BAD:
00338                         s = "Bad";
00339                         break;
00340 
00341                 case GPGME_SIG_STAT_NOKEY:
00342                         s = "No Key";
00343                         break;
00344 
00345                 case GPGME_SIG_STAT_ERROR:
00346                         s = "Error";
00347                         break;
00348 
00349                 case GPGME_SIG_STAT_DIFF:
00350                         s = "More than one signature";
00351                         break;
00352         }
00353         return s;
00354 }
00355 
00356 static const char *
00357 validity_string(GpgmeValidity val)
00358 {
00359         const char *s = "?";
00360 
00361         switch (val) {
00362                 case GPGME_VALIDITY_UNKNOWN:
00363                         s = "unknown";
00364                         break;
00365 
00366                 case GPGME_VALIDITY_NEVER:
00367                         s = "not trusted";
00368                         break;
00369 
00370                 case GPGME_VALIDITY_MARGINAL:
00371                         s = "marginal trusted";
00372                         break;
00373 
00374                 case GPGME_VALIDITY_FULL:
00375                         s = "fully trusted";
00376                         break;
00377 
00378                 case GPGME_VALIDITY_UNDEFINED:
00379                 case GPGME_VALIDITY_ULTIMATE:
00380                         break;
00381         }
00382         return s;
00383 }
00384 
00385 static void
00386 print_sig_stat(GpgmeCtx ctx, GpgmeSigStat status)
00387 {
00388         const char *s;
00389         time_t created;
00390         int idx;
00391         GpgmeKey key;
00392 
00393         dprintf(dGPG, "Verification Status: %s\n", status_string(status));
00394     
00395         for(idx=0; (s=gpgme_get_sig_status(ctx, idx, &status, &created));
00396                                                                         idx++) {
00397                 dprintf(dGPG, "sig %d: created: %lu expires: %lu status: %s\n",
00398                         idx, (unsigned long)created, 
00399                         gpgme_get_sig_ulong_attr(ctx, idx, GPGME_ATTR_EXPIRE,0),
00400                         status_string(status));
00401                 dprintf(dGPG, "sig %d: fpr/keyid: `%s' validity: %s\n",
00402                         idx, s,
00403                         validity_string(gpgme_get_sig_ulong_attr
00404                                 (ctx, idx, GPGME_ATTR_VALIDITY, 0)));
00405                 if (!gpgme_get_sig_key(ctx, idx, &key)) {
00406                         char *p = gpgme_key_get_as_xml(key);
00407                         dprintf(dGPG, "sig %d: key object:\n%s\n", idx, p);
00408                         free(p);
00409                         gpgme_key_release(key);
00410                 }
00411         }
00412 }
00413 
00414 
00415 char *
00416 JGetSignature(char *text, char *sig)
00417 {
00418         GpgmeCtx ctx;
00419         GpgmeError err;
00420         GpgmeData gsig, gtext;
00421         GpgmeSigStat status;
00422         char *retdata;
00423         char *sigdata;
00424         char buf[100];
00425         size_t nread;
00426         size_t retsz;
00427         time_t created;
00428         int idx;
00429         const char *s;
00430 
00431         retdata = strdup("");
00432         retsz = 0;
00433 
00434         err = gpgme_new(&ctx);
00435         if (err) {
00436                 dprintf(dGPG, "Failed to create GPGME context.\n");
00437                 return NULL;
00438         }
00439 
00440         err = gpgme_data_new_from_mem(&gtext, text, strlen(text), 0);
00441         if (err) {
00442                 dprintf(dGPG, "Failed to create text data.\n");
00443                 return NULL;
00444         }
00445 
00446         sigdata = (char *)malloc(sizeof(char) * (strlen(sig) + 1 + 72));
00447         sprintf(sigdata, "-----BEGIN PGP SIGNATURE-----\nVersion: JWGC\n\n%s\n-----END PGP SIGNATURE-----\n", sig);
00448         dprintf(dGPG, "Parsing input data:\n%s\n", sigdata);
00449         err = gpgme_data_new_from_mem(&gsig, sigdata, strlen(sigdata), 0);
00450         if (err) {
00451                 dprintf(dGPG, "Failed to create sig data.\n");
00452                 return NULL;
00453         }
00454 
00455         err = gpgme_op_verify(ctx, gsig, gtext, &status);
00456         if (err) {
00457                 dprintf(dGPG, "Data verification failed.\n");
00458                 return NULL;
00459         }
00460 
00461         print_sig_stat(ctx, status);
00462 
00463         fflush(NULL);
00464 
00465         idx = 0;
00466         s = gpgme_get_sig_status(ctx, idx, &status, &created);
00467         if (!s) {
00468                 dprintf(dGPG, "Unable to determine signature.\n");
00469                 return NULL;
00470         }
00471         retdata = strdup(s);
00472 
00473         gpgme_data_release(gsig);
00474         gpgme_data_release(gtext);
00475         gpgme_release(ctx);
00476 
00477         dprintf(dGPG, "Successfully verified signature:\n%s\n", retdata);
00478 
00479         return retdata;
00480 }
00481 
00482 void
00483 insert_into_key_list(char *jid, char *key)
00484 {
00485         int i, k;
00486         xode s;
00487 
00488         num_keys++;
00489         key_list = realloc(key_list, sizeof(xode) * (num_keys));
00490         key_list[num_keys - 1] = malloc(sizeof(xode));
00491 
00492         for (i = 0; i < (num_keys - 1) &&
00493              (strcasecmp(jid, xode_get_attrib(key_list[i], "jid")) > 0);
00494              i++);
00495 
00496         for (k = (num_keys - 1); k > i; k--) {
00497                 key_list[k] = key_list[k - 1];
00498         }
00499 
00500         key_list[k] = xode_new("key");
00501         xode_put_attrib(key_list[k], "jid", jid);
00502         xode_put_attrib(key_list[k], "id", key);
00503 }
00504 
00505 void
00506 JUpdateKeyList(char *jid, char *textstring, char *sigstring)
00507 {
00508         int i;
00509         char *key;
00510 
00511         key = JGetSignature(textstring, sigstring);
00512         if (!key) {
00513                 dprintf(dGPG, "No valid key returned, skipping.\n");
00514                 return;
00515         }
00516 
00517         dprintf(dGPG, "KeyID is %s\n", key);
00518 
00519         for (i = 0; i < num_keys; i++) {
00520                 if (!strcasecmp(xode_get_attrib(key_list[i], "jid"), jid)) {
00521                         xode_hide_attrib(key_list[i], "id");
00522                         xode_put_attrib(key_list[i], "id", key);
00523                         return;
00524                 }
00525         }
00526 
00527         insert_into_key_list(jid, key);
00528 }
00529 
00530 char *
00531 JGetKeyID(char *jid)
00532 {
00533         int i;
00534         char *key;
00535 
00536         for (i = 0; i < num_keys; i++) {
00537                 if (!strcasecmp(xode_get_attrib(key_list[i], "jid"), jid)) {
00538                         key = xode_get_attrib(key_list[i], "id");
00539                         return key;
00540                 }
00541         }
00542 
00543         return NULL;
00544 }
00545 #endif /* USE_GPGME */


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye