COMMAND

    pgp4pine

SYSTEMS AFFECTED

    pgp4pine-1.75-6

PROBLEM

    V.  Alex  Brennen  (CryptNET  Security  Advisory) found following.
    pgp4pine  is  a  program  which  is  used to interface various PGP
    implementations  with  the  popular  Pine  mail  reading  package.
    Version  1.75-6  of  pgp4pine  fails  to properly identify expired
    keys  when  working  with  the  Gnu Privacy Guard program (GnuPG).
    This  failure  may  result   in  the  transmission  of   sensitive
    information in clear text across the network.

    Version  1.75-6  of  pgp4pine  does  not  include code to check if
    public keys are expired when  loading keys from the GnuPG  openPGP
    implementation.   If a  user has  an expired  public key  in their
    keyring and attempts to encrypt a message to a recipient with that
    expired public key, pgp4pine will  fail to recognize that the  key
    is  expired.   pgp4pine  will  then  issue  a  command to GnuPG to
    encrypt the email  message with the  expired key.   The encryption
    will not be successful, GnuPG will return an error message due  to
    the  invalid  key.   pgp4pine  will  not  detect  the  error which
    occurred when  encrypting the  text and  will return  program flow
    control  to  Pine.   Pine  will  then  transmit the message in the
    clear.  No notice that an  error occurred will be provided to  the
    user by pgp4pine.

    To duplicate the error on the command line:

        bash$ pgp4pine -e -i /tmp/in.tmp -o /tmp/out.tmp -r (*R)

    * Where  R  is  a  recipient  with  an expired public key in  your
      keyring.

SOLUTION

    A patch, written by V.  Alex Brennen, has been provided  with this
    advisory.  The  patch consists of  code modifications which  allow
    pgp4pine to recognize  and ignore expired  keys when working  with
    GnuPG.

    diff -urN pgp4pine-1.75/pgp4pine/keyrings.c vab.pgp4pine-1.75/pgp4pine/keyrings.c
    --- pgp4pine-1.75/pgp4pine/keyrings.c   Fri Aug 18 09:24:45 2000
    +++ vab.pgp4pine-1.75/pgp4pine/keyrings.c       Mon Feb 12 21:03:09 2001
    @@ -449,22 +449,36 @@
                            if (strchr(buf,':') != NULL) {
                                    strncpy(keyType,getItem(buf,':',1),3);
                                    lineType = 0;
    -                               if (strcmp(keyType,"sec") == 0) lineType = 1; /* secret line... */
    -                               if (strcmp(keyType,"pub") == 0) lineType = 2; /* public key     */
    -                               if (strcmp(keyType,"uid") == 0) lineType = 4; /* user id        */
    -
    +                                /*
    +                                        The letter e in the second field of the colon delimited GnuPG
    +                                        output denotes that gpg asserts that the trust on this item
    +                                        has expired (perhaps as the result of an expired openPGP type
    +                                        0x13 or 0x18 signature packet).  If this line denotes a public
    +                                        key, GnuPG will not function with this key.  So, we should
    +                                        return with out adding it to the list.  We shouldn't check
    +                                        expiration ourselves because GnuPG is the final authority.
    +                                          - V. Alex Brennen, CryptNET FCAP [http://www.cryptnet.net/]
    +                                            2001.02.13.01.13.47
    +                                */
    +                                strncpy(tmpString,getItem(buf,':',2),1);
    +                                if (strcmp(tmpString,"e") == 0) lineType = -1; /* Line w/ expired trust */
    +                               else if (strcmp(keyType,"sec") == 0) lineType = 1; /* secret line... */
    +                               else if (strcmp(keyType,"pub") == 0) lineType = 2; /* public key     */
    +                               else if (strcmp(keyType,"uid") == 0) lineType = 4; /* user id        */
    +
                                    if (lineType == 1) inSec = 1;
    -                               if (lineType == 2) inSec = 0;
    +                               else if (lineType == 2) inSec = 0;
    
                                    switch (lineType) {
                                    case 1:
                                    case 2:
                                            if (lineType == 2 && getSecretOnly) break;
    +
                                            myNewKey = (struct pkiKey *) myMalloc(sizeof(pkiKeyStruct));
                                            if (firstKey == NULL) firstKey = myNewKey;
                                            if (oldKey != NULL) oldKey->nextKey = myNewKey;
                                            oldKey = myNewKey;
    -
    +
                                            /* next, key size... */
                                            strncpy(tmpString,getItem(buf,':',3),KEY_SIZE_LENGTH);
                                            strncpy(myNewKey->keySize,tmpString,KEY_SIZE_LENGTH);
    @@ -523,6 +537,8 @@
                                                    strncpy(myNewKey->emailAddress,extractEmailAddress(tmpString),EMAIL_ADDRESS_MAX_LENGTH);
                                            }
                                            break;
    +                                default:
    +                                        break;
                                    }
                            }
                    }