Signed Message
The simplest kind of signed OpenPGP message is just a literal data packet, with a One-Pass Signature Packet in front, and the actual Signature Packet after it:
The reason for using a One-Pass Signature Packet is that it allows both the sender and the recipient to hash the literal data and compute/verify the signature in one pass, hence the name. This allows for streaming operation at both ends.
If we compare the One-Pass Signature Packet and the Signature Packet, we see striking similarities:
By looking at the One-Pass Signature Packet, the recipient has all the information necessary to decide whether and how to compute the hash while processing the literal data packet. The hash algorithm field specifies which hash algorithm to use to digest the data, and the public-key algorithm field and the signer’s KeyID specifies who made the signature and what public-key algorithm was used. Now, if the recipient does not posses the signers public key, she might decide not to compute the digest at all.
-----BEGIN PGP MESSAGE-----
xA0DAAoWCTXiD9yZ2YYByxRiAAAAAABIZWxsbywgd29ybGQhCsJ1BAAWCgAnBYJc
dpUyFiEEjeZMrRdY/BlFYM9ZCTXiD9yZ2YYJEAk14g/cmdmGAAC5AgD/U/FD8PPq
qABrkdg9bV4aToP6YENgXGq8M7SIvTaznl0BAM1KdOKsUWPQgh5AJp3kOUzSO7v+
brfw03O1wQaOmgsH
=PdfA
-----END PGP MESSAGE-----
If there are multiple signatures, then the One-Pass Signature Packet and the associated Signature Packet “bracket” the packets in between.
Now, an interesting bit is the Last field of the One-Pass Signature Packet. If we want to have a signature with two signatures, there are two distinct interpretations: Either both signatures are over the same data, or one signature is over the data, and the other one is over the first signature and the data. The Last field let’s us express both.
The Last field groups One-Pass Signature Packet together. A sequence of One-Pass Signature Packets with the last one having the Last flag set signs the same data. In this case, both signatures are over the Literal Data Packet. This is the above message, with a new signature over the same data:
-----BEGIN PGP MESSAGE-----
xA0DAAoWCTXiD9yZ2YYAxA0DAAoW+zdR8Vh9rvEByxRiAAAAAABIZWxsbywgd29y
bGQhCsJ1BAAWCgAnBYJcdp0PFiEEOdEAq2fVvYwEAQIF+zdR8Vh9rvEJEPs3UfFY
fa7xAACTpAEA26VdXBZ9D9apeNQYXBGdMCXgE5uVnvvQJdNkqRCw5GUBANwvh1Kx
Q6+qHv9lXTIamCpd7BDmGYkBHtfY7ucESiELwnUEABYKACcFglx2lTIWIQSN5kyt
F1j8GUVgz1kJNeIP3JnZhgkQCTXiD9yZ2YYAALkCAP9T8UPw8+qoAGuR2D1tXhpO
g/pgQ2BcarwztIi9NrOeXQEAzUp04qxRY9CCHkAmneQ5TNI7u/5ut/DTc7XBBo6a
Cwc=
=SbrT
-----END PGP MESSAGE-----
On the other hand, if we want to sign, or notarize, the existing signature, we instead compute the signature over the existing signature and the data, and set the last flag to indicate that this is a notarization:
Taking the first message and adding a notarization yields:
-----BEGIN PGP MESSAGE-----
xA0DAAoW+zdR8Vh9rvEBxA0DAAoWCTXiD9yZ2YYByxRiAAAAAABIZWxsbywgd29y
bGQhCsJ1BAAWCgAnBYJcdpUyFiEEjeZMrRdY/BlFYM9ZCTXiD9yZ2YYJEAk14g/c
mdmGAAC5AgD/U/FD8PPqqABrkdg9bV4aToP6YENgXGq8M7SIvTaznl0BAM1KdOKs
UWPQgh5AJp3kOUzSO7v+brfw03O1wQaOmgsHwnUEABYKACcFglx2nggWIQQ50QCr
Z9W9jAQBAgX7N1HxWH2u8QkQ+zdR8Vh9rvEAAE/1AP4oKycMGFYOzh/XgE51rmgJ
DH4PnkVDuyiqSktXpiXk2QEAlt/KkCxV+0/QfoSvCPjLqfoQ01st0a3w1QqzbDeg
zA4=
=5U6S
-----END PGP MESSAGE-----
Note the “Level” indicator of the Signature Packets. The first is a level 0 signature, a signature over data, whereas the second signature is a level 1 signature, a notarization over all level 0 signatures and the Literal Data Packet.
If you want to learn more about OpenPGP’s Signature Packet, see section 5.2 of RFC4880. The One-Pass Signature Packet is described in section 5.4 of RFC4880.