diff -c pgp_263i/crypto.c pgp_sha1/crypto.c
*** pgp_263i/crypto.c   Wed Jun 19 22:14:21 1996
--- pgp_sha1/crypto.c   Wed Jun 19 22:45:58 1996
***************
*** 74,80 ****
--- 74,86 ----

 /* 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;
***************
*** 734,739 ****
--- 740,752 ----
               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");
***************
*** 751,758 ****
--- 764,781 ----
               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;
***************
*** 764,771 ****
--- 787,803 ----
       }

       /* 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,
***************
*** 823,828 ****
--- 855,865 ----
               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 */
***************
*** 893,898 ****
--- 930,938 ----
               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];
***************
*** 907,912 ****
--- 947,961 ----
  "signfile: infile = '%s', outfile = '%s', mode = '%c', literalfile = '%s'\n"
,
                       infile,outfile,EXT_C(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 */

***************
*** 930,938 ****
--- 979,1000 ----
               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() */
***************
*** 1088,1093 ****
--- 1150,1158 ----
       }
       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) {
***************
*** 1246,1251 ****
--- 1311,1319 ----
                                     error return. */
               }

+ #ifdef SHA1
+               local_sha1_flag = FALSE;
+ #endif
               certificate_length =
                 make_signature_certificate(certificate, &MD,
                                            K0_SIGNATURE_BYTE, e, d, p, q,
***************
*** 1382,1388 ****
--- 1450,1461 ----
       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 */
***************
*** 1409,1414 ****
--- 1482,1490 ----
       extern Boolean bad_separate_signature;
 #endif
       int             outbufoffset;
+ #ifdef SHA1
+       local_sha1_flag = FALSE;
+ #endif

       fill0( keyID, KEYFRAGSIZE );

***************
*** 1486,1491 ****
--- 1562,1572 ----
               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;

***************
*** 1686,1692 ****
--- 1767,1778 ----
       /*==================================================================*/
       /* 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\
***************
*** 1714,1720 ****
--- 1800,1812 ----
       }

       /* 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])
***************
*** 1729,1737 ****
--- 1821,1839 ----
       /* 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 */

***************
*** 1741,1747 ****
--- 1843,1853 ----

       /* 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
***************
*** 1766,1772 ****
--- 1872,1889 ----
                          != 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);

***************
*** 1777,1788 ****
--- 1894,1913 ----
                               /* 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
               if (checksig_pass == 1) { /* Bad signature - try one more pass
with other charset */
                       checksig_pass++;
                       return -1;
***************
*** 1819,1824 ****
--- 1944,1955 ----
       fprintf(pgpout,
 LANG("Signature made %s using %d-bit key, key ID %s\n"),
                 ctdate((word32 *)timestamp), countbits(n), key2IDstring(n));
+ #ifdef SHA1
+       if (local_sha1_flag)
+               fprintf(pgpout,
+ LANG("Signature made using the SHA1 message digest algorithm.\n"));
+       local_sha1_flag = FALSE;
+ #endif
 #ifdef MACTC5
       AddResult((char *)userid);
 #endif
diff -c pgp_263i/pgp.c pgp_sha1/pgp.c
*** pgp_263i/pgp.c      Wed Jun 19 22:14:24 1996
--- pgp_sha1/pgp.c      Wed Jun 19 22:22:17 1996
***************
*** 161,166 ****
--- 161,170 ----
 void Exit(int x);
 #endif

+ #ifdef SHA1
+ #include "sha1.h"
+ #endif
+
 #ifdef  M_XENIX
 char *strstr();
 long time();
***************
*** 894,899 ****
--- 898,906 ----
       case 'w':
           wipeflag = TRUE;
           break;
+     case 'x':
+       mdalg_flag = SHA1_ALGORITHM_BYTE;
+       break;
       case 'z':
           break;
           /* '+' special option: does not require - */
diff -c pgp_263i/rsaglue1.c pgp_sha1/rsaglue1.c
*** pgp_263i/rsaglue1.c Wed Jun 19 22:14:35 1996
--- pgp_sha1/rsaglue1.c Thu Jun 20 07:27:44 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_263i/rsaglue2.c pgp_sha1/rsaglue2.c
*** pgp_263i/rsaglue2.c Wed Jun 19 22:14:21 1996
--- pgp_sha1/rsaglue2.c Fri Jun 21 17:41:47 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 */