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.
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:
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:
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.