pgp-integration man page on MirBSD

Man page or keyword search:  
man Server   6113 pages
apropos Keyword Search (all sections)
Output format
MirBSD logo
[printable version]

PGP(7)				  User Manual				PGP(7)

DESCRIPTION
       This document describes the process of integrating PGP with third party
       applications.

STRATEGIES
       There are two basic possible strategies for  PGP	 integration:	source
       level  (calling the PGP libraries directly) and executable level (using
       system(2) or some other method to call the PGP executables).

       This document will not detail the library method at  this  time.	  When
       PGP  5.5	 is  released,	all support will be migrated to the new Source
       Development Kit (SDK) from the existing APIs.  Developers  are  encour‐
       aged  to	 either use the executable integration method detailed here or
       wait for the SDK to be released.

EXECUTABLE INTEGRATION
       The most straightforward means of integrating  PGP  support  into  your
       application  is	to open input and output pipes to the PGP executables.
       For a very thorough example  of	PGP  integration,  see	the  "plugins"
       directory of the PGP 5.0 source distribution, which has a patch for the
       mutt email client.  Most of the ideas in this  text  are	 a  result  of
       experiences modifying Michael Elkins' PGP integration code from mutt.

       The basic strategy is to use the PGP executables to perform encryption,
       decryption and verification.  While it is possible to take a much  more
       complex	approach  (for	example,  Mr. Elkins' code actually parses the
       output of pgpk(1) in order to present users with a list of  keys),  the
       more complex efforts are outside the scope of this document.

       All examples are in "C", and assume the following variables:

       char *recipients; /*A space-delimited list of message recipients*/
       char *buf;	 /*The message to be operated on*/
       char *passphrase; /*The user's passphrase*/

       All  allocation	is  assumed  already  handled by the application.  The
       reader is assumed to be familiar with concepts of C programming and  to
       have  read  and understood the pgp.cfg(5) man page.  Also be aware that
       the following code assumes all buffers are big enough and isn't	always
       perfect	about handling errors gracefully.  This should be considered a
       starting point, not a complete system.

COMMON ROUTINE
       The following routine uses fork(2) and pipe(2) to open  both  read  and
       write  file  handles  to	 a child process.  It is used to invoke PGP in
       these examples.	You may use it effectively without  understanding  how
       it works.

       /*Runs cmd, and hooks in to the process' stdin, and out to its stdout.
	*Inspiration stolen from Michael Elkins; see mutt for how to do this
	*properly with error checking, etc.
	*/
       int run_pgp(char *cmd, FILE **in, FILE **out)
       {
	 int pin[2], pout[2], child_pid;

	 *in = *out = NULL;

	 pipe(pin);
	 pipe(pout);

	 if(!(child_pid = fork()))
	 {
	   /*We're the child.*/
	   close(pin[1]);
	   dup2(pin[0], 0);
	   close(pin[0]);

	   close(pout[0]);
	   dup2(pout[1], 1);
	   close(pout[1]);

	   execl("/bin/sh", "sh", "-c", cmd, NULL);
	   _exit(127);
	 }

	 /*Only get here if we're the parent.*/
	 close(pout[1]);
	 *out = fdopen(pout[0], "r");

	 close(pin[0]);
	 *in = fdopen(pin[1], "w");

	 return(child_pid);
       }

ENCRYPTION
       The  easiest case is to simply pass your buffer to PGP.	The most mini‐
       mal form of this would be to write your data out, and have PGP  encrypt
       it.   Unfortunately,  this would mean that the cleartext document would
       be placed on the hard drive, which is undesirable.  However, we can use
       PGP's stream mode (the -f option) to get PGP to accept the plaintext on
       stdin and place the encrypted text on stdout:

       /*Takes the buffer you wish to encrypt and the recipients; writes the
	*result into encrypt_buffer.
	*/
       void encrypt_buffer(char *buf, char *recipients)
       {
	 FILE *pgpin, *pgpout;
	 char sys_buf[256], tmpbuf[1024] = "\0";

	 sprintf(sys_buf, "pgpe -at -r %s -f +batchmode=1", recipients);
	 run_pgp(sys_buf, &pgpin, &pgpout); /*Execute PGP*/
	 if(pgpin && pgpout)
	 {
	   /*Output buffer to PGP:*/
	   fwrite(buf, sizeof(char), strlen(buf), pgpin);
	   fclose(pgpin);

	   /*Now, read the result back from PGP:*/
	   *buf = '\0';
	   fgets(tmpbuf, sizeof(tmpbuf), pgpout);
	   while(!feof(pgpout))
	   {
	      strcat(buf, tmpbuf);
	      fgets(tmpbuf, sizeof(tmpbuf), pgpout);
	   }
	   fclose(pgpout);
	 }
       }

       Additional functionality would include using the -s flag	 to  sign  the
       message	if  the user so requested.  Implementation is quite similar to
       the pgps(1) integration, shown next.

       If you find that PGP is mysteriously failing during this step,  it  may
       be  because  you	 are encrypting to keys that are not completely valid.
       By default, PGP will fail during batch mode when this  is  encountered.
       The solution is to place NoBatchInvalidKeys = off in your pgp.cfg file.
       It is requested that you not pass this option on the command  line,  as
       some users will prefer not to encrypt to invalid keys.

SIGNING
       Conceptually,  signing  is  quite  similar, but with a twist - the user
       must specify a passphrase!  The simple way to handle this is  to	 allow
       PGP  to	ask the user for the passphrase.  However, if you wish to hide
       PGP's functionality a little bit more, you may  wish  to	 ask  for  the
       passphrase yourself, prior to signing, and pass it through.

       There  are  a number of ways to get the passphrase to PGP, but the best
       is probably using the environment variable PGPPASSFD.  This allows  you
       to  specify  a file descriptor on which you will pass the passphrase as
       the first input.	 Commonly, this is set to 0, stdin:

       /*Signs a buffer.  The output is placed in buf.*/
       void sign_buffer(char *buf, char *passphrase)
       {
	 FILE *pgpin, *pgpout;
	 char tmpbuf[1024] = " ";

	 setenv("PGPPASSFD", "0", 1);
	 run_pgp("pgps -at -f +batchmode=1", &pgpin, &pgpout);
	 if(pgpin && pgpout)
	 {
	   fprintf(pgpin, "%s\n", passphrase); /*Send the passphrase in, first*/
	   memset(passphrase, '\0', strlen(passphrase)); /*Burn the passphrase*/
	   fwrite(buf, sizeof(char), strlen(buf), pgpin);
	   fclose(pgpin);

	   *buf = '\0';
	   fgets(tmpbuf, sizeof(tmpbuf), pgpout);
	   while(!feof(pgpout))
	   {
	     strcat(buf, tmpbuf);
	     fgets(tmpbuf, sizeof(tmpbuf), pgpout);
	   }

	   wait(NULL);

	   fclose(pgpout);
	 }
	 unsetenv("PGPPASSFD");
       }

       Note the use of memset(3) to clear  the	passphrase  immediately	 after
       use.   Not  clearing  the  passphrase  can  result in numerous security
       issues.

DECRYPTION/VERIFICATION
       Decryption is almost identical to signing (the same passphrase require‐
       ments apply).  The options passed in are slightly different, however:

       /*Verifies a PGP buffer.	 Note that, if the buffer is only signed, the
	*passphrase may be unnecessary - a complete program should probably
	*check for the "BEGIN PGP SIGNED MESSAGE" tag before prompting the
	*user for a passphrase.	 The output is placed in buf, as well.
	*/
       void verify_buffer(char *buf, char *passphrase)
       {
	 FILE *pgpin, *pgpout;
	 char tmpbuf[1024] = " ";

	 setenv("PGPPASSFD", "0", 1);
	 run_pgp("pgpv -f +batchmode=1 +OutputInformationFD=1",
		 &pgpin, &pgpout);
	 if(pgpin && pgpout)
	 {
	   fprintf(pgpin, "%s\n", passphrase); /*Send the passphrase in, first*/
	   memset(passphrase, '\0', strlen(passphrase)); /*Burn the passphrase*/
	   fprintf(pgpin, "%s", buf);
	   fclose(pgpin);

	   *buf = '\0';
	   fgets(tmpbuf, sizeof(tmpbuf), pgpout);
	   while(!feof(pgpout))
	   {
	     strcat(buf, tmpbuf);
	     fgets(tmpbuf, sizeof(tmpbuf), pgpout);
	   }

	   wait(NULL);

	   fclose(pgpout);
	 }
	 unsetenv("PGPPASSFD");
       }

       The  +OutputInformationFD option is used to have PGP output information
       about the message (in this case, who signed it, if anyone) on the  same
       stream as the decrypted or verified data.

CONFIGURATION OPTIONS
       Application  integrators are encourages to read the pgp.cfg(5) documen‐
       tation, which details how to pass configuration options on the  command
       line, including the public and private keyrings your application wishes
       to use.

SEE ALSO
       pgp5(1), pgpe(1), pgpv(1),  pgps(1),  pgpk(1),  http://www.pgp.com  (US
       versions) and http://www.pgpi.com (International versions)

PGP			       JULY 1997 (v5.0)				PGP(7)
[top]

List of man pages available for MirBSD

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net