diff -c pgp_262/crypto.c pgp_sha1/crypto.c
*** pgp_262/crypto.c    Fri Jun 21 23:31:01 1996
--- pgp_sha1/crypto.c   Sat Jun 22 00:02:32 1996
***************
*** 63,69 ****
--- 63,75 ----

 /* This variable stores the md5 hash of the current file, if it is
    available.  It is used in make_random_ideakey. */
+ #ifdef SHA1
+ #include "sha1.h"
+ static boolean local_sha1_flag = FALSE;
+ static unsigned char md5buf[20];
+ #else
 static unsigned char md5buf[16];
+ #endif

 /* This flag is set if the buffer above has been filled. */
 static char already_have_md5 = 0;
***************
*** 697,702 ****
--- 703,715 ----
               complete message digest packet in a single RSA block. */

               blocksize = countbytes(n)-1;    /* size of a plaintext block */
+ #ifdef SHA1
+               if ((blocksize < 32) && local_sha1_flag) {
+                       fprintf(pgpout,
+    "\n\007Error: RSA key length must be at least 264 bits.\n");
+                       return -1;
+               } else
+ #endif
               if (blocksize < 31) {
                       fprintf(pgpout,
    "\n\007Error: RSA key length must be at least 256 bits.\n");
***************
*** 714,721 ****
--- 727,744 ----
               convert_byteorder(timestamp,4); /* convert to external form */

       /* Finish off message digest calculation with this information */
+ #ifdef SHA1
+       if (local_sha1_flag) {
+               SHA1_addbuffer ((struct SHA1Context *)MD, &class, 1, 0);
+               SHA1_addbuffer ((struct SHA1Context *)MD, timestamp, 4, md5buf)
;
+       } else {
+               MD_addbuffer (MD, &class, 1, 0);
+               MD_addbuffer (MD, timestamp, 4, md5buf);
+       }
+ #else
       MD_addbuffer (MD, &class, 1, 0);
       MD_addbuffer (MD, timestamp, 4, md5buf);
+ #endif
 /* We wrote the digest to a static variable because we want to keep it around
    for random number generation later.   Also make a note of that fact. */
       already_have_md5 = 1;
***************
*** 727,734 ****
--- 750,766 ----
       }

       /* do RSA signature calculation: */
+ #ifdef SHA1
+       if (local_sha1_flag)
+               i = rsa_private_encrypt((unitptr)outbuf, md5buf, 20,
+                               e, d, p, q, u, n);
+       else
+               i = rsa_private_encrypt((unitptr)outbuf, md5buf, 16,
+                               e, d, p, q, u, n);
+ #else
       i = rsa_private_encrypt((unitptr)outbuf, md5buf, sizeof(md5buf),
                               e, d, p, q, u, n);
+ #endif
       if (i < 0) {
               if (i == -4) {
                       fprintf(pgpout,
***************
*** 786,791 ****
--- 818,828 ----
               certificate[certificate_length++] = keyID[i];

       certificate[certificate_length++] = RSA_ALGORITHM_BYTE;
+ #ifdef SHA1
+       if (local_sha1_flag)
+       certificate[certificate_length++] = SHA1_ALGORITHM_BYTE;
+       else
+ #endif
       certificate[certificate_length++] = MD5_ALGORITHM_BYTE;

       /* Now append first two bytes of message digest */
***************
*** 855,860 ****
--- 892,900 ----
               char keyfile[MAX_PATH];
               int status;
               struct MD5Context MD;
+ #ifdef SHA1
+               struct SHA1Context SH;
+ #endif
               byte keyID[KEYFRAGSIZE];
               unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION];
               unit d[MAX_UNIT_PRECISION];
***************
*** 869,874 ****
--- 909,923 ----
  "signfile: infile = '%s', outfile = '%s', mode = '%c', literalfile = '%s'\n"
,
                       infile,outfile,lit_mode,literalfile);

+ #ifdef SHA1
+               local_sha1_flag = FALSE;
+               if (mdalg_flag == SHA1_ALGORITHM_BYTE)
+               {
+               if (SHA1file(&SH, infile) < 0)
+                       return -1; /* problem with input file.  error return */
+               }
+               else
+ #endif
               if (MDfile(&MD, infile) < 0)
                       return -1; /* problem with input file.  error return */

***************
*** 893,901 ****
--- 942,963 ----
               if (lit_mode==MODE_TEXT) signature_class = SM_SIGNATURE_BYTE;
               else signature_class = SB_SIGNATURE_BYTE;

+ #ifdef SHA1
+               if (mdalg_flag == SHA1_ALGORITHM_BYTE)
+               {
+               local_sha1_flag = TRUE;
+               certificate_length = make_signature_certificate(certificate,
+                                                               (struct MD5Cont
ext *)&SH,
+                       signature_class, e, d, p, q, u, n);
+               }
+               else
+ #endif
               certificate_length = make_signature_certificate(certificate,
                                                               &MD,
                       signature_class, e, d, p, q, u, n);
+ #ifdef SHA1
+               local_sha1_flag = FALSE;
+ #endif
               if (certificate_length < 0)
                       return -1;      /* error return from
                                          make_signature_certificate() */
***************
*** 1051,1056 ****
--- 1113,1121 ----
       }
       set_precision(prec);

+ #ifdef SHA1
+       local_sha1_flag = FALSE;
+ #endif
       certificate_length = make_signature_certificate(certificate, &MD,
               KC_SIGNATURE_BYTE, e, d, p, q, u, n);
       if (certificate_length < 0) {
***************
*** 1242,1247 ****
--- 1307,1315 ----
                                     error return. */
               }

+ #ifdef SHA1
+               local_sha1_flag = FALSE;
+ #endif
               certificate_length =
                 make_signature_certificate(certificate, &MD,
                                            K0_SIGNATURE_BYTE, e, d, p, q,
***************
*** 1322,1328 ****
--- 1390,1401 ----
       word32 dummystamp;
       byte userid[256];
       struct MD5Context MD;
+ #ifdef SHA1
+       struct SHA1Context SH;
+       byte digest[20];
+ #else
       byte digest[16];
+ #endif
       boolean separate_signature;
       boolean fixedLiteral = FALSE; /* Whether it's a fixed literal2
                                        packet */
***************
*** 1345,1350 ****
--- 1418,1426 ----
       short   fdl_len;
 #endif
       int             outbufoffset;
+ #ifdef SHA1
+       local_sha1_flag = FALSE;
+ #endif

       fill0( keyID, KEYFRAGSIZE );

***************
*** 1422,1427 ****
--- 1498,1508 ----
               goto err1;

       algorithm = *certificate++;
+ #ifdef SHA1
+       if (algorithm == SHA1_ALGORITHM_BYTE)
+       local_sha1_flag = TRUE;
+       else
+ #endif
       if (version_error(algorithm, MD5_ALGORITHM_BYTE))
               goto err1;

***************
*** 1610,1616 ****
--- 1691,1702 ----
       /*==================================================================*/
       /* Look at nested stuff within RSA block... */

+ #ifdef SHA1
+       if (count == -7 || (count > 0 && local_sha1_flag && count != 20)
+                                       || (count > 0 && !local_sha1_flag && co
unt != 16))
+ #else
       if (count == -7 || (count > 0 && count != sizeof(digest)))
+ #endif
       {
               fputs(LANG("\007\nUnrecognized message digest algorithm.\n\
 This may require a newer version of PGP.\n\
***************
*** 1640,1646 ****
--- 1726,1738 ----
       }

       /* Distinguish PKCS-compatible from pre-3.3 which has an extra byte */
+ #ifdef SHA1
+       outbufoffset = (count==16) ? 0 : 1;
+       if (local_sha1_flag)
+               outbufoffset = 0;
+ #else
       outbufoffset = (count==sizeof(digest)) ? 0 : 1;
+ #endif

       if (outbuf[outbufoffset] != mdlow2[0]  ||
               outbuf[outbufoffset+1] != mdlow2[1])
***************
*** 1655,1663 ****
--- 1747,1765 ----
       /* Reposition file to where that plaintext begins... */
       fseek(f,start_text,SEEK_SET); /* reposition file from last ftell */

+ #ifdef SHA1
+       if (local_sha1_flag)
+       SHA1file0_len(&SH,f,text_len);
+       else
+ #endif
       MDfile0_len(&MD,f,text_len); /* compute a message digest from
                                       rest of file */

+ #ifdef SHA1
+       if (local_sha1_flag)
+       SHA1_addbuffer (&SH, mdextras, mdlensave, digest);
+       else
+ #endif
       MD_addbuffer (&MD, mdextras, mdlensave, digest); /* Finish message
                                                           digest */

***************
*** 1667,1673 ****
--- 1769,1779 ----

       /* now compare computed MD with claimed MD */
 /* Assume MSB external byte ordering */
+ #ifdef SHA1
+       if (!equal_buffers(digest, outbuf+outbufoffset, local_sha1_flag ? 20 :
16)) {
+ #else
       if (!equal_buffers(digest, outbuf+outbufoffset, 16)) {
+ #endif
               /* IF the signature is bad, AND this machine does not use
                  MSDOS-stype canonical text as its native text format, AND
                  this is a detached signature certificate, AND this file
***************
*** 1692,1698 ****
--- 1798,1815 ----
                          != NULL )
                       {
                               /* Now check the signature */
+ #ifdef SHA1
+                               if (local_sha1_flag)
+                               SHA1file0_len(&SH, tempFile, -1L );
+                               else
+ #endif
                               MDfile0_len(&MD, tempFile, -1L );
+ #ifdef SHA1
+                               if (local_sha1_flag)
+                               SHA1_addbuffer(&SH, mdextras, mdlensave,
+                                            digest);
+                               else
+ #endif
                               MD_addbuffer(&MD, mdextras, mdlensave,
                                            digest);

***************
*** 1703,1714 ****
--- 1820,1839 ----
                               /* Check if the signature is OK this time
                                  round */
 /* Assume MSB external byte ordering */
+ #ifdef SHA1
                               if(equal_buffers(digest, outbuf+outbufoffset,
+                                                local_sha1_flag ? 20 : 16))
+ #else
+                               if(equal_buffers(digest, outbuf+outbufoffset,
                                                16))
+ #endif
                                       goto goodsig;
                       }
               }

+ #ifdef SHA1
+               local_sha1_flag = FALSE;
+ #endif
               fprintf(pgpout,
 LANG("\007\nWARNING: Bad signature, doesn't match file contents!\007\n"));
               fprintf(pgpout,LANG("\nBad signature from user \"%s\".\n"),
***************
*** 1730,1735 ****
--- 1855,1866 ----
               LOCAL_CHARSET((char *)userid));
       fprintf(pgpout,
 LANG("Signature made %s\n"),ctdate((word32 *)timestamp));
+ #ifdef SHA1
+       if (local_sha1_flag)
+               fprintf(pgpout,
+ LANG("Signature made using the SHA1 message digest algorithm.\n"));
+       local_sha1_flag = FALSE;
+ #endif

 warnsig:
       /* warn only, don't ask if user wants to use the key */
diff -c pgp_262/pgp.c pgp_sha1/pgp.c
*** pgp_262/pgp.c       Fri Jun 21 23:31:16 1996
--- pgp_sha1/pgp.c      Sat Jun 22 07:16:22 1996
***************
*** 131,136 ****
--- 131,141 ----
 #include "keymaint.h"
 #include "keyadd.h"
 #include "rsaglue.h"
+
+ #ifdef SHA1
+ #include "sha1.h"
+ #endif
+
 #ifdef  M_XENIX
 char *strstr();
 long time();
***************
*** 661,666 ****
--- 666,674 ----
       case 'w':
           wipeflag = TRUE;
           break;
+       case 'x':
+          mdalg_flag = SHA1_ALGORITHM_BYTE;
+          break;
       case 'z':
           break;
           /* '+' special option: does not require - */
diff -c pgp_262/rsaglue1.c pgp_sha1/rsaglue1.c
*** pgp_262/rsaglue1.c  Fri Jun 21 23:31:17 1996
--- pgp_sha1/rsaglue1.c Sat Jun 22 07:22:07 1996
***************
*** 53,58 ****
--- 53,99 ----
 static byte asn_array[] = {   /* PKCS 01 block type 01 data */
       0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
       0x02,0x05,0x05,0x00,0x04,0x10 };
+ #ifdef SHA1
+ static byte sha1_asn_array[] = {
+       0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,
+       0x05,0x00,0x04,0x14 };
+ /*
+ Taken from Internet Draft draft-ietf-cat-spkmgss-06,
+ "The Simple Public-Key GSS-API Mechanism (SPKM)", by
+ C. Adams, Bell-Northern Research, Jan. 19, 1996.  See
+ also "Working Implementation Agreements for Open Systems
+ Interconnection Protocols: Part 12 - OS Security, Output
+ from  the   December  1994   Open  Systems   Environment
+ Implementors' Workshop (OIW)"
+
+          SHA1 OBJECT IDENTIFIER ::= {
+             iso(1) identified-organization(3) oiw(14) secsig(3)
+             algorithm(2) 26
+          }
+
+ ASN.1 encoding:
+   0x30, / * Universal, Constructed, Sequence * /
+         0x21, / * Length 33 (bytes following) * /
+                 0x30, / * Universal, Constructed, Sequence * /
+                 0x09, / * Length 9 * /
+                         0x06, / * Universal, Primitive, object-identifier * /
+                         0x05, / * Length 5 * /
+                                 43, / * 43 = ISO(1)*40 + 3 * /
+                                 14,
+                                 3,
+                                 2,
+                                 26,
+                         0x05, / * Universal, Primitive, NULL * /
+                         0x00, / * Length 0 * /
+                 0x04, / * Universal, Primitive, Octet string * /
+                 0x14 / * Length 20 * /
+                         / * 20 SHA.1 digest bytes go here * /
+
+ Cf. "A Layman's Guide to a Subset of ASN.1, BER, and DER --
+ An RSA Laboratories Technical Note" by Burton S. Kaliski Jr.
+ Revised November 1, 1993
+ */
+ #endif /* SHA1 */
 /* This many bytes from the end, there's a zero byte */
 #define ASN_ZERO_END 3

***************
*** 144,149 ****
--- 185,195 ----
               *p++ = 0;

       i = blocksize - 2 - bytes;              /* Padding needed */
+ #ifdef SHA1
+       if (bytes == 20)
+       i -= sizeof(sha1_asn_array);            /* Space for type encoding */
+       else
+ #endif
       i -= sizeof(asn_array);         /* Space for type encoding */
       if (i < 0) {
               i = -4;                 /* Error code */
***************
*** 153,160 ****
--- 199,215 ----
       memset(p, ~0, i);               /* All 1's padding */
       p += i;
       *p++ = 0;                       /* Zero framing byte */
+ #ifdef SHA1
+       if (bytes == 20) {
+       memcpy(p, sha1_asn_array, sizeof(sha1_asn_array)); /* ASN data */
+       p += sizeof(sha1_asn_array);
+       } else {
+ #endif
       memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
       p += sizeof(asn_array);
+ #ifdef SHA1
+       }
+ #endif
       memcpy(p, inbuf, bytes);        /* User data */

       mp_convert_order((byte *)temp);
***************
*** 241,250 ****
--- 296,315 ----
               if (front[-1])  /* First non-FF byte should be 0 */
                       goto ErrorReturn;
               /* Then comes the ASN header */
+ #ifdef SHA1
+       if (memcmp(front, asn_array, sizeof(asn_array))) {
+               if (memcmp(front, sha1_asn_array, sizeof(sha1_asn_array))) {
+                       mp_burn(temp);
+                       return -7;
+               }
+               front += sizeof(sha1_asn_array);
+       } else
+ #else
               if (memcmp(front, asn_array, sizeof(asn_array))) {
                       mp_burn(temp);
                       return -7;
               }
+ #endif
               front += sizeof(asn_array);
       }

diff -c pgp_262/rsaglue2.c pgp_sha1/rsaglue2.c
*** pgp_262/rsaglue2.c  Fri Jun 21 23:31:02 1996
--- pgp_sha1/rsaglue2.c Sat Jun 22 07:27:59 1996
***************
*** 175,180 ****
--- 175,221 ----
 static byte asn_array[] = {   /* PKCS 01 block type 01 data */
       0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
       0x02,0x05,0x05,0x00,0x04,0x10 };
+ #ifdef SHA1
+ static byte sha1_asn_array[] = {
+       0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,
+       0x05,0x00,0x04,0x14 };
+ /*
+ Taken from Internet Draft draft-ietf-cat-spkmgss-06,
+ "The Simple Public-Key GSS-API Mechanism (SPKM)", by
+ C. Adams, Bell-Northern Research, Jan. 19, 1996.  See
+ also "Working Implementation Agreements for Open Systems
+ Interconnection Protocols: Part 12 - OS Security, Output
+ from  the   December  1994   Open  Systems   Environment
+ Implementors' Workshop (OIW)"
+
+          SHA1 OBJECT IDENTIFIER ::= {
+             iso(1) identified-organization(3) oiw(14) secsig(3)
+             algorithm(2) 26
+          }
+
+ ASN.1 encoding:
+   0x30, / * Universal, Constructed, Sequence * /
+         0x21, / * Length 33 (bytes following) * /
+                 0x30, / * Universal, Constructed, Sequence * /
+                 0x09, / * Length 9 * /
+                         0x06, / * Universal, Primitive, object-identifier * /
+                         0x05, / * Length 5 * /
+                                 43, / * 43 = ISO(1)*40 + 3 * /
+                                 14,
+                                 3,
+                                 2,
+                                 26,
+                         0x05, / * Universal, Primitive, NULL * /
+                         0x00, / * Length 0 * /
+                 0x04, / * Universal, Primitive, Octet string * /
+                 0x14 / * Length 20 * /
+                         / * 20 SHA.1 digest bytes go here * /
+
+ Cf. "A Layman's Guide to a Subset of ASN.1, BER, and DER --
+ An RSA Laboratories Technical Note" by Burton S. Kaliski Jr.
+ Revised November 1, 1993
+ */
+ #endif /* SHA1 */
 /* This many bytes from the end, there's a zero byte */
 #define ASN_ZERO_END 3

***************
*** 263,272 ****
--- 304,328 ----
       i = make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
       if (i < 0)
               goto Cleanup;
+ #ifdef SHA1
+       if (bytes == 20) {
+       memcpy(p, sha1_asn_array, sizeof(sha1_asn_array)); /* ASN data */
+       p += sizeof(sha1_asn_array);
+       } else {
+ #endif
       memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
       p += sizeof(asn_array);
+ #ifdef SHA1
+       }
+ #endif
       memcpy(p, inbuf, bytes);        /* User data */
       /* Pad and encrypt */
+ #ifdef SHA1
+       if (bytes == 20)
+       i = RSAPrivateEncrypt((byte *)temp, &blocksize,
+                             (byte *)temp, bytes+sizeof(sha1_asn_array), &Priv
Key);
+       else
+ #endif
       i = RSAPrivateEncrypt((byte *)temp, &blocksize,
                             (byte *)temp, bytes+sizeof(asn_array), &PrivKey);
       burn(PrivKey);
***************
*** 322,331 ****
--- 378,397 ----
       front = (byte *)temp;
       back = front+blocksize;

+ #ifdef SHA1
+       if (memcmp(front, asn_array, sizeof(asn_array))) {
+               if (memcmp(front, sha1_asn_array, sizeof(sha1_asn_array))) {
+                       mp_burn(temp);
+                       return -7;
+               }
+               front += sizeof(sha1_asn_array);
+       } else
+ #else
       if (memcmp(front, asn_array, sizeof(asn_array))) {
               mp_burn(temp);
               return -7;
       }
+ #endif
       front += sizeof(asn_array);

 /* We're done - copy user data to outbuf */