A weakness in PGP signatures, and a suggested solution (long)

I've been engaged in a lively debate with a few members of the cypherpunks mailing list about forgeries that are hard to repudiate even if PGP signatures are used. One of the participants suggested that I post a summary to alt.privacy.pgp and sci.crypt, which is just what I'm doing. (My apologies to the mail.cypherpunks readers who already saw much of this once.) I'll illustrate the problem with several scenarios of forgeries. (It's funny that earlier today I was showing a friend how easy it is to post forgeries. She seemed suitably impressed. :) Scenario 1: Bob once sent Carol an e-mail that looked like this: ----------------------------------------------------------------------- From: Bob@boxb To: Carol@boxc Date: 25 Dec 1965 Subject: Carol, we're history Message-ID: <111@boxb> ----BEGIN PGP SIGNED MESSAGE---- I no longer wish to go out with you. Merry Christmas! ----BEGIN PGP SIGNATURE---- Version 2.6.2 12341234... ----END PGP SIGNATURE---- ----------------------------------------------------------------------- Carol can forge an e-mail to Alice that looks like this: ----------------------------------------------------------------------- From: Bob@boxb To: Alice@boxa Date: 25 Dec 1995 Subject: Alice, we're history Message-ID: <222@bobb> ----BEGIN PGP SIGNED MESSAGE---- I no longer wish to go out with you. Merry Christmas! ----BEGIN PGP SIGNATURE---- Version 2.6.2 12341234... ----END PGP SIGNATURE---- ----------------------------------------------------------------------- We assume that it's easy for Carol to forge the RFC 822 headers to make it look like the e-mail came from Bob. That's why many of us use digital signatures. The signed portion of Bob's original e-mail did not state that the message is addressed to Carol (e.g., "Dear Carol"). Alice will probably verify that the signature matches Bob's private key and assume that the e-mail is authentic and has been sent to her by Bob. To repudiate the e-mail, Bob might have to point out that the "Received:" headers differ from his usual e-mails, without relying on PGP. In fact, the presense of his verifiable signature would create more of a presumption of authenticity of Alice's part. Scenario 2: Bob sends the same e-mail as above to Carol. David, a rogue sysadmin, gets a copy of the e-mail, forges the same e-mail as above to Alice. Scenario 3: Bob sends a signed e-mail to Alice. Alice sees it in her newsfeed, forges a Usenet article, makes it look like it came from Bob, and includes the body of Bob's e-mail as the body of the Usenet forgery. Usenet forgeries are easy. Again, if the signed text happens to be suitable, then Bob will have difficulty repudiating the forgery. He won't not be able to use the PGP signature, which will in fact verify. Hopefully, he'll be able to point out that the RFC 1036 Path: header is different from his usual header (which may not be the case). Many Usenet readers would be unconvinced and Bob's reputation would be damaged. Scenario 4: Bob posts a signed Usenet article to alt.sex. Alice forges a usenet article in Bob's name to misc.kids, recycilng the signed body, which would probably be considered inappropriate for misc.kids. Same result as #3. Scenario 5: Bob posts a signed Usenet article to some innocuous newsgroup. Alice reposts the same body in a forgery in Bob's name. The forgery can be cross-posted to numerous "inappropriate" newsgroups ("velveeta"), or multi-posted ("spam"). Certain rogue self-apponited net.cops forge cancels for all copies of Bob's article, including the original. (They are a bigger menace than the forgers :) (As several people know, I have been a victim of some of the above-described kinds of forgeries.) I think the underlying problem is that the way PGP signatures are used by most people, they validate a text, but allow it to be quoted out of context in an e-mail or Usenet forgery. I suggest to the kind folks working on PGP 3 that there should be a standard protocol to include within the signed portion the information on when and for whom this text is written: i.e. the list of e-mail recipients and/or Usenet newsgroups, which could be easily compared with the RFC 822/1036 headers of an e-mail/Usenet article. Perhaps there could be a new option for PGP to look _outside_ the signed block and match the headers with what's inside the block. For example, suppose the signature block says: this text was written by alice@zog.org, posted to alt.sex and alt.sex.banal and e-mailed to bob@masons.com. Suppose PGP is asked to check the signature in a file that purports to be a e-mail or a Usenet article and has some headers before the signed portion. If there is a list of To: recipients, and it includes someone other than the recipients listed within the signed block; or if there is a Newsgroups: header, and it includes newsgroups not listed within the signed portion; then the input is bogus. For compatibility with the existing software, if the signed block doesn't include this info, then this checking should't be done, of course. After I posted the above suggestion to cypherpunks, one very respected member of that list informed me that "the security multiparts standard (RFC 1848) includes a provision for signing the headers as well as the body of a message. The security multiparts can be used with PGP, and there is even an Internet Draft for it (draft-elkins-pem-pgp-02.txt), but there is not yet consensus for adopting this as a standard on the pgp-mime mailing list." I hope my examples will convince some that present practice of signing pieces of text which can be quoted out of context in a forgery is just not enough. We need to have an easy way to sign the headers without resorting to mine. --- Dr. Dimitri Vulis Brighton Beach Boardwalk BBS, Forest Hills, N.Y.: +1-718-261-2013, 14.4Kbps

-----BEGIN PGP SIGNED MESSAGE----- Newsgroups: alt.security.pgp,sci.crypt,mail.cypherpunks In article <oTTsgD7w165w@bwalk.dm.com>, Dr. Dimitri Vulis <dlv@bwalk.dm.com> wrote:
I'll illustrate the problem with several scenarios of forgeries.
The easy way around this if you think this might happen is just to put a line at the top of your signed message stating where the message is supposed to go. Then if people see it elsewhere, they can figure out that something is amiss. See above for an example. -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQEVAwUBMON8jiJFQNhhNdm5AQHCFgf9GbaCMWRckNQA4y9Av8e0nigYP0GpGxEh 0A2w9dvSJBmuzaMJ8QxERieGVE61U3+VXOLgssdWXZsnqOPBNKk+2hYyx+vatFL9 XKETZV245acLo4VMNNxV4m/hGteuHUb4oQEKCWHwylyh/f9wfvx+ZTjvTyd8RiqQ nwcpRPhRA4FozOaVNbjZw/A4nmvxq5I3gg3yMet3vfMWKdhLIy4gsvuhRm/asTGo BUSw8PIJQbFbrXpoyWsP/sWGDa5tjN7Z05HnX9yU3OIa0uk6K6e2xKVJUo3G2Jso Kts/pw2hqDBJ0K8XFsnicmncnUDz+FGNKqyCGsSFY8TlaVowpNFZJw== =VpDg -----END PGP SIGNATURE----- -- Chris Adams (cadams@HiWAAY.net) Finger for PGP public key "So, if anybody wants to have hardware sent to them: don't call me, but instead write your own unix operating system. It has worked every time for me." - Linus Torvalds, author of Linux (Unix-like) OS

START <attila> I never paid much attention to the problem other than to avoid it by forcing it --i.e. list the destination and the send inside the signature block, thus: ----------------- BEGIN PGP SIGNED TEXT To: john doe <john@box.com> Newsgroups: sci.crypt From: jane roe <jane@topsey.turvey.com> Subject: that's all folks! John, don't darken my door during the Christmas holidays. Nevermore. jane ---------------- BEGIN PGP SIGNATURE ERTYUIKJBNM,./34567JM,./ ---------------- END PGP SIGNATURE with e-mail, e-letters, direct faxes, etc. it is to easy to ignore the courtesy header. From a standpoint of security, you have blown away each of the attacks outline in your article in so much as the signature will not compute if the courtesy block is omitted. personally, I do not think PGP 3 should attempt to solve the problem. Most of the headers involved are applied _after_ the message leaves the mail program; and, PGP interfaces are virtually the same as invoking an alternate editor, which gets you nothing. END <attila> -- -------------------------------------------------------------------- #!/bin/perl -s-- -export-a-crypto-system-sig -RSA-3-lines-PERL $m=unpack(H.$w,$m."\0"x$w),$_=`echo "16do$w 2+4Oi0$d*-^1[d2%Sa 2/d0<X+d*La1=z\U$n%0]SX$k"[$m*]\EszlXx++p|dc`,s/^.|\W//g,print pack('H*',$_)while read(STDIN,$m,($w=2*$d-1+length$n&~1)/2)

attila <attila@primenet.com> writes:
I never paid much attention to the problem other than to avoid it by forcing it --i.e. list the destination and the send inside the signature block, thus:
----------------- BEGIN PGP SIGNED TEXT
To: john doe <john@box.com> Newsgroups: sci.crypt From: jane roe <jane@topsey.turvey.com> Subject: that's all folks! ...
Good - that's just what I've proposed :). However right now the overwhelming majority of people who PGP-sign their writings, don't include a copy of the headers within the signed portion. Those few who do, all seem to use different formats, so the signed headers cannot be easily compared to the headers in the actual envelope by a program. I propose a format below.
with e-mail, e-letters, direct faxes, etc. it is to easy to ignore the courtesy header. From a standpoint of security, you have blown away each of the attacks outline in your article in so much as the signature will not compute if the courtesy block is omitted.
I totally agree; that's why I propose copying that info in the signed portion "by default".
personally, I do not think PGP 3 should attempt to solve the problem. Most of the headers involved are applied _after_ the message leaves the mail program; and, PGP interfaces are virtually the same as invoking an alternate editor, which gets you nothing.
I don't think that a protocol for signing headers that requires mime/multipart is going to be widely used, especially for Usenet postings. I've thought about it and came up with the following idea for the syntax: ----BEGIN PGP SIGNED MESSAGE---- some text ----BEGIN PGP SIGNED HEADERS---- From: address [all these are optional] To: address[,address]... Newsgroups: group[,group]... Date: rfc 822 date Subject: subject ----BEGIN PGP SIGNATURE---- Version 2.6.2 12341234... ----END PGP SIGNATURE---- The "signed headers" portion may contain the following optional fields: From: address -- the address associated with the key used to sign this message To: address[,address]... -- addresses (user@host, no names) of the recipients in RFC 822 To: and Cc: headers (not the Bcc: recipients). Addresses mangled by various gateways shouldn't verify. Newsgroups: group[,group]... -- the newsgroups from the RFC 1036 header Date: and Subject: -- should match the header The sequence of events would be: * pick the addressees and the newsgroups + compose the text * sign the signed portion * post/e-mail the result to the specified addressees/newsgroups. (Of course, the poster could lie and claim in the signed portion that the article is being posted to alt.sex.pedo when he himself posts it to misc.kids:) If a standard like this catches on, and is integrated into PGP-aware news/e-mail programs, then it's a simple exercise to write a little script to look for BEGIN PGP SIGNED HEADERS and compare the information inside it with the RFC 822/1036 headers outside the signed portion of the message. It could be done within PGP too. --- Dr. Dimitri Vulis Brighton Beach Boardwalk BBS, Forest Hills, N.Y.: +1-718-261-2013, 14.4Kbps

-----BEGIN PGP SIGNED MESSAGE----- [sample implementation for Gnus is included]
"Dimitri" == Dimitri Vulis <dlv@bwalk.dm.com> writes:
Dimitri> I propose a format below. See the PGP header block attached to this message as an example of this proposed format. atilla> with e-mail, e-letters, direct faxes, etc. it is to easy atilla> to ignore the courtesy header. From a standpoint of atilla> security, you have blown away each of the attacks outline atilla> in your article in so much as the signature will not atilla> compute if the courtesy block is omitted. Dimitri> I totally agree; that's why I propose copying that info Dimitri> in the signed portion "by default". atilla> personally, I do not think PGP 3 should attempt to solve atilla> the problem. Most of the headers involved are applied atilla> _after_ the message leaves the mail program; and, PGP atilla> interfaces are virtually the same as invoking an alternate atilla> editor, which gets you nothing. I agree. Besides, this whole thing can be done with the existing PGP. Date: and Message-ID: are two, and they need to be signed. Date: is a further problem with Gnus, since the format of the displayed date is user customizable, but that's a separate issue. ... Dimitri> The "signed headers" portion may contain the following Dimitri> optional fields: Dimitri> From: address -- the address associated with the key used Dimitri> to sign this message It's easier to deal with whatever is being used as the From: in the message. ... Dimitri> (Of course, the poster could lie and claim in the signed Dimitri> portion that the article is being posted to alt.sex.pedo Dimitri> when he himself posts it to misc.kids:) So you would also include the Message-ID:. Dimitri> If a standard like this catches on, and is integrated Dimitri> into PGP-aware news/e-mail programs, then it's a simple Dimitri> exercise to write a little script to look for BEGIN PGP Dimitri> SIGNED HEADERS and compare the information inside it with Dimitri> the RFC 822/1036 headers outside the signed portion of Dimitri> the message. It could be done within PGP too. This is basically a Good Idea, and can be implemented using existing tools. Here is some to code to implement it for Gnus. Verification of the headers is left (at present) as an exercise for the reader. ;;; Add this to your .gnus and call ;;; gnus-article-sign-message instead of mc-sign directly. ;;; Pgp signed messages are vulnerable to various kinds of badness due to ;;; the separation of header information. Fix it. (defconst gnus-pgp-included-headers '("From" "To" "Newsgroups" "Message-ID" "Date" "Subject" "Cc" "Gcc") "Headers to include in signed portion of PGP signed message.") (defconst gnus-pgp-signed-headers "----BEGIN PGP SIGNED HEADERS----\n" "String to use for separation in message.") (defun gnus-article-sign-message (arg) "Sign a message with PGP, including outgoing headers in an included block, as per the suggestion of \"Dr. Dimitri Vulis\" <dlv@bwalk.dm.com>." (interactive "p") (save-excursion (save-restriction (gnus-inews-narrow-to-headers) (goto-char (point-max)) (or (mail-fetch-field "date") (insert (concat "Date: " (gnus-inews-date) "\n"))) (or (mail-fetch-field "message-id") (insert (concat "Message-ID: " (gnus-inews-message-id) "\n"))))) (save-excursion (goto-char (point-max)) (insert "\n") ;; If there is already a header block (eg. after undoing a signature) ;; remove it entirely, and rebuild from scratch. (if (re-search-backward gnus-pgp-signed-headers nil t) (kill-region (point) (point-max))) (insert gnus-pgp-signed-headers) (let ((headers gnus-pgp-included-headers) header header-value) (while (setq header (car headers)) (setq headers (cdr headers)) (save-excursion (save-restriction (gnus-narrow-to-headers) (setq header-value (mail-fetch-field header)))) (if header-value (insert (concat header ": " header-value "\n")))) (insert "\n"))) (mc-sign arg)) - -- steve@miranova.com baur - ----BEGIN PGP SIGNED HEADERS---- To: cypherpunks@toad.com Message-ID: <m2n38am8ht.fsf@diana.miranova.com> Date: 30 Dec 1995 15:34:22 -0800 Subject: Re: easy avoidance of PGP signature forgeries and reuse -----BEGIN PGP SIGNATURE----- Version: 2.6.2 Comment: Processed by Mailcrypt 3.4, an Emacs/PGP interface iQCVAwUBMOXMhKLJZEUiepcNAQGjtgP/ZnC+TL4cbFL3RF+o8fwe2YFciqGkOWX9 VuPK4btnvfKF/wcdMTfJoUKbSutKcwRkbLe5fAqEV3qrXwM7PgfNMlXfcgNg44It UhfLAaFg6ke5ArWr9EZfyFcD93OrS9qVGU7emSenmsqpdJUE6jU0HmKAQkZzP1Ak AYQD7ow/tzI= =PTV7 -----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE----- Dr. Dimitri Vulis writes:
I suggest to the kind folks working on PGP 3 that there should be a standard protocol to include within the signed portion the information on when and for whom this text is written: i.e. the list of e-mail recipients and/or Usenet newsgroups, which could be easily compared with the RFC 822/1036 headers of an e-mail/Usenet article.
This assumes that every Usenet site uses RFC 822/1036 headers locally. This is no real-world assumption. And the clearsign problem can be solved with MIME only, since currently, the MIME 8-bit character set conversion will kill the validity of signatures, regardless whether being forged or not. Since I know this, I seldom use clearsigning. Quite simply, it does not work, and that's a more severe problem. If an error on signature validation is the normality, not the exception, the whole stuff does not make any sense. hajo -----BEGIN PGP SIGNATURE----- Version: 2.6.2i Comment: Sig validation of clearsigned 8 bit text is uncertain. iQCVAwUBMORRda1Qa39mIA0ZAQELEAQAryOaVDZIhnYQETxhmHyJktRei3080gXV 77Oy5Qo3/WdO7cvFdR+CKytbZQlV7GHS4lQ+N0MCPHH79+vLnw8xvQ+3htkzerjF u6tgjiEnbR/YNCvjEq01aU2RVHgycg680WVOH4DqUNTi7yAY2G5Sc6K2LAD4AQrp toniWTWanyY= =+LZR -----END PGP SIGNATURE-----
participants (5)
-
attila
-
cadams@fly.HiWAAY.net
-
dlv@bwalk.dm.com
-
hajo@quijote.in-berlin.de
-
steve@miranova.com