OpenPGP message: GraphViz block diagram (.dot) source

The OpenPGP Message Format is a format to store encryption and signature keys for emails.

File extension

["gpg", "pub", "pgp"]

KS implementation details

License: MIT

References

This page hosts a formal specification of OpenPGP message using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

GraphViz block diagram source

openpgp_message.dot

digraph {
	rankdir=LR;
	node [shape=plaintext];
	subgraph cluster__openpgp_message {
		label="OpenpgpMessage";
		graph[style=dotted];

		openpgp_message__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
			<TR><TD PORT="packets_pos">0</TD><TD PORT="packets_size">...</TD><TD>Packet</TD><TD PORT="packets_type">packets</TD></TR>
			<TR><TD COLSPAN="4" PORT="packets__repeat">repeat to end of stream</TD></TR>
		</TABLE>>];
		subgraph cluster__preferred_hash_algorithms {
			label="OpenpgpMessage::PreferredHashAlgorithms";
			graph[style=dotted];

			preferred_hash_algorithms__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="algorithm_pos">0</TD><TD PORT="algorithm_size">1</TD><TD>u1→HashAlgorithms</TD><TD PORT="algorithm_type">algorithm</TD></TR>
				<TR><TD COLSPAN="4" PORT="algorithm__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__preferred_compression_algorithms {
			label="OpenpgpMessage::PreferredCompressionAlgorithms";
			graph[style=dotted];

			preferred_compression_algorithms__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="algorithm_pos">0</TD><TD PORT="algorithm_size">1</TD><TD>u1→CompressionAlgorithms</TD><TD PORT="algorithm_type">algorithm</TD></TR>
				<TR><TD COLSPAN="4" PORT="algorithm__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__signers_user_id {
			label="OpenpgpMessage::SignersUserId";
			graph[style=dotted];

			signers_user_id__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="user_id_pos">0</TD><TD PORT="user_id_size">⇲</TD><TD>str(UTF-8)</TD><TD PORT="user_id_type">user_id</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__secret_key_packet {
			label="OpenpgpMessage::SecretKeyPacket";
			graph[style=dotted];

			secret_key_packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="public_key_pos">0</TD><TD PORT="public_key_size">...</TD><TD>PublicKeyPacket</TD><TD PORT="public_key_type">public_key</TD></TR>
				<TR><TD PORT="string_to_key_pos">...</TD><TD PORT="string_to_key_size">1</TD><TD>u1</TD><TD PORT="string_to_key_type">string_to_key</TD></TR>
				<TR><TD PORT="symmetric_encryption_algorithm_pos">...</TD><TD PORT="symmetric_encryption_algorithm_size">1</TD><TD>u1→SymmetricKeyAlgorithm</TD><TD PORT="symmetric_encryption_algorithm_type">symmetric_encryption_algorithm</TD></TR>
				<TR><TD PORT="secret_key_pos">...</TD><TD PORT="secret_key_size">⇲</TD><TD></TD><TD PORT="secret_key_type">secret_key</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__key_server_preferences {
			label="OpenpgpMessage::KeyServerPreferences";
			graph[style=dotted];

			key_server_preferences__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="flag_pos">0</TD><TD PORT="flag_size">1</TD><TD>u1→ServerFlags</TD><TD PORT="flag_type">flag</TD></TR>
				<TR><TD COLSPAN="4" PORT="flag__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__regular_expression {
			label="OpenpgpMessage::RegularExpression";
			graph[style=dotted];

			regular_expression__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="regex_pos">0</TD><TD PORT="regex_size">...</TD><TD>str(UTF-8)</TD><TD PORT="regex_type">regex</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__subpackets {
			label="OpenpgpMessage::Subpackets";
			graph[style=dotted];

			subpackets__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="subpacketss_pos">0</TD><TD PORT="subpacketss_size">...</TD><TD>Subpacket</TD><TD PORT="subpacketss_type">subpacketss</TD></TR>
				<TR><TD COLSPAN="4" PORT="subpacketss__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__revocation_key {
			label="OpenpgpMessage::RevocationKey";
			graph[style=dotted];

			revocation_key__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="class_pos">0</TD><TD PORT="class_size">1</TD><TD>u1</TD><TD PORT="class_type">class</TD></TR>
				<TR><TD PORT="public_key_algorithm_pos">1</TD><TD PORT="public_key_algorithm_size">1</TD><TD>u1→PublicKeyAlgorithms</TD><TD PORT="public_key_algorithm_type">public_key_algorithm</TD></TR>
				<TR><TD PORT="fingerprint_pos">2</TD><TD PORT="fingerprint_size">20</TD><TD></TD><TD PORT="fingerprint_type">fingerprint</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__user_id_packet {
			label="OpenpgpMessage::UserIdPacket";
			graph[style=dotted];

			user_id_packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="user_id_pos">0</TD><TD PORT="user_id_size">⇲</TD><TD>str(UTF-8)</TD><TD PORT="user_id_type">user_id</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__policy_uri {
			label="OpenpgpMessage::PolicyUri";
			graph[style=dotted];

			policy_uri__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="uri_pos">0</TD><TD PORT="uri_size">⇲</TD><TD>str(UTF-8)</TD><TD PORT="uri_type">uri</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__signature_target {
			label="OpenpgpMessage::SignatureTarget";
			graph[style=dotted];

			signature_target__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="public_key_algorithm_pos">0</TD><TD PORT="public_key_algorithm_size">1</TD><TD>u1→PublicKeyAlgorithms</TD><TD PORT="public_key_algorithm_type">public_key_algorithm</TD></TR>
				<TR><TD PORT="hash_algorithm_pos">1</TD><TD PORT="hash_algorithm_size">1</TD><TD>u1→HashAlgorithms</TD><TD PORT="hash_algorithm_type">hash_algorithm</TD></TR>
				<TR><TD PORT="hash_pos">2</TD><TD PORT="hash_size">⇲</TD><TD></TD><TD PORT="hash_type">hash</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__key_flags {
			label="OpenpgpMessage::KeyFlags";
			graph[style=dotted];

			key_flags__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="flag_pos">0</TD><TD PORT="flag_size">1</TD><TD>u1→KeyFlags</TD><TD PORT="flag_type">flag</TD></TR>
				<TR><TD COLSPAN="4" PORT="flag__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__features {
			label="OpenpgpMessage::Features";
			graph[style=dotted];

			features__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="flags_pos">0</TD><TD PORT="flags_size">⇲</TD><TD></TD><TD PORT="flags_type">flags</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__primary_user_id {
			label="OpenpgpMessage::PrimaryUserId";
			graph[style=dotted];

			primary_user_id__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="user_id_pos">0</TD><TD PORT="user_id_size">1</TD><TD>u1</TD><TD PORT="user_id_type">user_id</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__subpacket {
			label="OpenpgpMessage::Subpacket";
			graph[style=dotted];

			subpacket__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="len_pos">0</TD><TD PORT="len_size">6</TD><TD>LenSubpacket</TD><TD PORT="len_type">len</TD></TR>
				<TR><TD PORT="subpacket_type_pos">6</TD><TD PORT="subpacket_type_size">1</TD><TD>u1→SubpacketTypes</TD><TD PORT="subpacket_type_type">subpacket_type</TD></TR>
				<TR><TD PORT="content_pos">7</TD><TD PORT="content_size">...</TD><TD>switch (subpacket_type)</TD><TD PORT="content_type">content</TD></TR>
			</TABLE>>];
subpacket__seq_content_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
	<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
	<TR><TD>:subpacket_types_exportable_certification</TD><TD PORT="case0">ExportableCertification</TD></TR>
	<TR><TD>:subpacket_types_preferred_hash_algorithms</TD><TD PORT="case1">PreferredHashAlgorithms</TD></TR>
	<TR><TD>:subpacket_types_embedded_signature</TD><TD PORT="case2">EmbeddedSignature</TD></TR>
	<TR><TD>:subpacket_types_trust_signature</TD><TD PORT="case3">TrustSignature</TD></TR>
	<TR><TD>:subpacket_types_reason_for_revocation</TD><TD PORT="case4">ReasonForRevocation</TD></TR>
	<TR><TD>:subpacket_types_features</TD><TD PORT="case5">Features</TD></TR>
	<TR><TD>:subpacket_types_signature_expiration_time</TD><TD PORT="case6">SignatureExpirationTime</TD></TR>
	<TR><TD>:subpacket_types_preferred_compression_algorithms</TD><TD PORT="case7">PreferredCompressionAlgorithms</TD></TR>
	<TR><TD>:subpacket_types_revocable</TD><TD PORT="case8">Revocable</TD></TR>
	<TR><TD>:subpacket_types_regular_expression</TD><TD PORT="case9">RegularExpression</TD></TR>
	<TR><TD>:subpacket_types_notation_data</TD><TD PORT="case10">NotationData</TD></TR>
	<TR><TD>:subpacket_types_key_expiration_time</TD><TD PORT="case11">KeyExpirationTime</TD></TR>
	<TR><TD>:subpacket_types_signature_creation_time</TD><TD PORT="case12">SignatureCreationTime</TD></TR>
	<TR><TD>:subpacket_types_revocation_key</TD><TD PORT="case13">RevocationKey</TD></TR>
	<TR><TD>:subpacket_types_key_flags</TD><TD PORT="case14">KeyFlags</TD></TR>
	<TR><TD>:subpacket_types_issuer</TD><TD PORT="case15">Issuer</TD></TR>
	<TR><TD>:subpacket_types_signature_target</TD><TD PORT="case16">SignatureTarget</TD></TR>
	<TR><TD>:subpacket_types_key_server_preferences</TD><TD PORT="case17">KeyServerPreferences</TD></TR>
	<TR><TD>:subpacket_types_signers_user_id</TD><TD PORT="case18">SignersUserId</TD></TR>
	<TR><TD>:subpacket_types_policy_uri</TD><TD PORT="case19">PolicyUri</TD></TR>
	<TR><TD>:subpacket_types_preferred_key_server</TD><TD PORT="case20">PreferredKeyServer</TD></TR>
	<TR><TD>:subpacket_types_primary_user_id</TD><TD PORT="case21">PrimaryUserId</TD></TR>
</TABLE>>];
		}
		subgraph cluster__old_packet {
			label="OpenpgpMessage::OldPacket";
			graph[style=dotted];

			old_packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="len_pos">0</TD><TD PORT="len_size">...</TD><TD>switch (_parent.len_type)</TD><TD PORT="len_type">len</TD></TR>
				<TR><TD PORT="body_pos">...</TD><TD PORT="body_size">...</TD><TD>switch (_parent.packet_type_old)</TD><TD PORT="body_type">body</TD></TR>
			</TABLE>>];
old_packet__seq_len_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
	<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
</TABLE>>];
old_packet__seq_body_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
	<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
	<TR><TD>:packet_tags_public_key_packet</TD><TD PORT="case0">PublicKeyPacket</TD></TR>
	<TR><TD>:packet_tags_secret_subkey_packet</TD><TD PORT="case1">PublicKeyPacket</TD></TR>
	<TR><TD>:packet_tags_user_id_packet</TD><TD PORT="case2">UserIdPacket</TD></TR>
	<TR><TD>:packet_tags_secret_key_packet</TD><TD PORT="case3">SecretKeyPacket</TD></TR>
	<TR><TD>:packet_tags_signature_packet</TD><TD PORT="case4">SignaturePacket</TD></TR>
	<TR><TD>:packet_tags_public_subkey_packet</TD><TD PORT="case5">PublicKeyPacket</TD></TR>
</TABLE>>];
		}
		subgraph cluster__issuer {
			label="OpenpgpMessage::Issuer";
			graph[style=dotted];

			issuer__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="keyid_pos">0</TD><TD PORT="keyid_size">8</TD><TD>u8be</TD><TD PORT="keyid_type">keyid</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__exportable_certification {
			label="OpenpgpMessage::ExportableCertification";
			graph[style=dotted];

			exportable_certification__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="exportable_pos">0</TD><TD PORT="exportable_size">1</TD><TD>u1</TD><TD PORT="exportable_type">exportable</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__signature_expiration_time {
			label="OpenpgpMessage::SignatureExpirationTime";
			graph[style=dotted];

			signature_expiration_time__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="time_pos">0</TD><TD PORT="time_size">4</TD><TD>u4be</TD><TD PORT="time_type">time</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__signature_creation_time {
			label="OpenpgpMessage::SignatureCreationTime";
			graph[style=dotted];

			signature_creation_time__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="time_pos">0</TD><TD PORT="time_size">4</TD><TD>u4be</TD><TD PORT="time_type">time</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__signature_packet {
			label="OpenpgpMessage::SignaturePacket";
			graph[style=dotted];

			signature_packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="version_pos">0</TD><TD PORT="version_size">1</TD><TD>u1</TD><TD PORT="version_type">version</TD></TR>
				<TR><TD PORT="signature_type_pos">1</TD><TD PORT="signature_type_size">1</TD><TD>u1</TD><TD PORT="signature_type_type">signature_type</TD></TR>
				<TR><TD PORT="public_key_algorithm_pos">2</TD><TD PORT="public_key_algorithm_size">1</TD><TD>u1→PublicKeyAlgorithms</TD><TD PORT="public_key_algorithm_type">public_key_algorithm</TD></TR>
				<TR><TD PORT="hash_algorithm_pos">3</TD><TD PORT="hash_algorithm_size">1</TD><TD>u1→HashAlgorithms</TD><TD PORT="hash_algorithm_type">hash_algorithm</TD></TR>
				<TR><TD PORT="len_hashed_subpacket_pos">4</TD><TD PORT="len_hashed_subpacket_size">2</TD><TD>u2be</TD><TD PORT="len_hashed_subpacket_type">len_hashed_subpacket</TD></TR>
				<TR><TD PORT="hashed_subpackets_pos">6</TD><TD PORT="hashed_subpackets_size">len_hashed_subpacket</TD><TD>Subpackets</TD><TD PORT="hashed_subpackets_type">hashed_subpackets</TD></TR>
				<TR><TD PORT="len_unhashed_subpacket_pos">...</TD><TD PORT="len_unhashed_subpacket_size">2</TD><TD>u2be</TD><TD PORT="len_unhashed_subpacket_type">len_unhashed_subpacket</TD></TR>
				<TR><TD PORT="unhashed_subpackets_pos">...</TD><TD PORT="unhashed_subpackets_size">len_unhashed_subpacket</TD><TD>Subpackets</TD><TD PORT="unhashed_subpackets_type">unhashed_subpackets</TD></TR>
				<TR><TD PORT="left_signed_hash_pos">...</TD><TD PORT="left_signed_hash_size">2</TD><TD>u2be</TD><TD PORT="left_signed_hash_type">left_signed_hash</TD></TR>
				<TR><TD PORT="rsa_n_pos">...</TD><TD PORT="rsa_n_size">2</TD><TD>u2be</TD><TD PORT="rsa_n_type">rsa_n</TD></TR>
				<TR><TD PORT="signature_pos">...</TD><TD PORT="signature_size">⇲</TD><TD></TD><TD PORT="signature_type">signature</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__revocable {
			label="OpenpgpMessage::Revocable";
			graph[style=dotted];

			revocable__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="revocable_pos">0</TD><TD PORT="revocable_size">1</TD><TD>u1</TD><TD PORT="revocable_type">revocable</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__embedded_signature {
			label="OpenpgpMessage::EmbeddedSignature";
			graph[style=dotted];

			embedded_signature__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="signature_packet_pos">0</TD><TD PORT="signature_packet_size">...</TD><TD>SignaturePacket</TD><TD PORT="signature_packet_type">signature_packet</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__preferred_key_server {
			label="OpenpgpMessage::PreferredKeyServer";
			graph[style=dotted];

			preferred_key_server__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="uri_pos">0</TD><TD PORT="uri_size">⇲</TD><TD>str(UTF-8)</TD><TD PORT="uri_type">uri</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__reason_for_revocation {
			label="OpenpgpMessage::ReasonForRevocation";
			graph[style=dotted];

			reason_for_revocation__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="revocation_code_pos">0</TD><TD PORT="revocation_code_size">1</TD><TD>u1→RevocationCodes</TD><TD PORT="revocation_code_type">revocation_code</TD></TR>
				<TR><TD PORT="reason_pos">1</TD><TD PORT="reason_size">⇲</TD><TD>str(UTF-8)</TD><TD PORT="reason_type">reason</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__len_subpacket {
			label="OpenpgpMessage::LenSubpacket";
			graph[style=dotted];

			len_subpacket__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="first_octet_pos">0</TD><TD PORT="first_octet_size">1</TD><TD>u1</TD><TD PORT="first_octet_type">first_octet</TD></TR>
				<TR><TD PORT="second_octet_pos">1</TD><TD PORT="second_octet_size">1</TD><TD>u1</TD><TD PORT="second_octet_type">second_octet</TD></TR>
				<TR><TD PORT="scalar_pos">2</TD><TD PORT="scalar_size">4</TD><TD>u4be</TD><TD PORT="scalar_type">scalar</TD></TR>
			</TABLE>>];
			len_subpacket__inst__len [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>len</TD><TD>(first_octet &lt; 192 ? first_octet : ( ((first_octet &gt;= 192) &amp;&amp; (first_octet &lt; 255))  ? ((((first_octet - 192) &lt;&lt; 8) + second_octet) + 192) : scalar))</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__notation_data {
			label="OpenpgpMessage::NotationData";
			graph[style=dotted];

			notation_data__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="flags_pos">0</TD><TD PORT="flags_size">4</TD><TD></TD><TD PORT="flags_type">flags</TD></TR>
				<TR><TD PORT="len_name_pos">4</TD><TD PORT="len_name_size">2</TD><TD>u2be</TD><TD PORT="len_name_type">len_name</TD></TR>
				<TR><TD PORT="len_value_pos">6</TD><TD PORT="len_value_size">2</TD><TD>u2be</TD><TD PORT="len_value_type">len_value</TD></TR>
				<TR><TD PORT="name_pos">8</TD><TD PORT="name_size">len_name</TD><TD></TD><TD PORT="name_type">name</TD></TR>
				<TR><TD PORT="value_pos">...</TD><TD PORT="value_size">len_value</TD><TD></TD><TD PORT="value_type">value</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__public_key_packet {
			label="OpenpgpMessage::PublicKeyPacket";
			graph[style=dotted];

			public_key_packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="version_pos">0</TD><TD PORT="version_size">1</TD><TD>u1</TD><TD PORT="version_type">version</TD></TR>
				<TR><TD PORT="timestamp_pos">1</TD><TD PORT="timestamp_size">4</TD><TD>u4be</TD><TD PORT="timestamp_type">timestamp</TD></TR>
				<TR><TD PORT="public_key_algorithm_pos">5</TD><TD PORT="public_key_algorithm_size">1</TD><TD>u1→PublicKeyAlgorithms</TD><TD PORT="public_key_algorithm_type">public_key_algorithm</TD></TR>
				<TR><TD PORT="len_alg_pos">6</TD><TD PORT="len_alg_size">2</TD><TD>u2be</TD><TD PORT="len_alg_type">len_alg</TD></TR>
				<TR><TD PORT="rsa_n_pos">8</TD><TD PORT="rsa_n_size">(len_alg / 8)</TD><TD></TD><TD PORT="rsa_n_type">rsa_n</TD></TR>
				<TR><TD PORT="padding_pos">...</TD><TD PORT="padding_size">2</TD><TD>u2be</TD><TD PORT="padding_type">padding</TD></TR>
				<TR><TD PORT="rsa_e_pos">...</TD><TD PORT="rsa_e_size">3</TD><TD></TD><TD PORT="rsa_e_type">rsa_e</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__key_expiration_time {
			label="OpenpgpMessage::KeyExpirationTime";
			graph[style=dotted];

			key_expiration_time__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="time_pos">0</TD><TD PORT="time_size">4</TD><TD>u4be</TD><TD PORT="time_type">time</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__packet {
			label="OpenpgpMessage::Packet";
			graph[style=dotted];

			packet__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="one_pos">0</TD><TD PORT="one_size">1b</TD><TD>BitsType1</TD><TD PORT="one_type">one</TD></TR>
				<TR><TD PORT="new_packet_format_pos">0:1</TD><TD PORT="new_packet_format_size">1b</TD><TD>BitsType1</TD><TD PORT="new_packet_format_type">new_packet_format</TD></TR>
				<TR><TD PORT="packet_type_new_pos">0:2</TD><TD PORT="packet_type_new_size">6b</TD><TD>b6→PacketTags</TD><TD PORT="packet_type_new_type">packet_type_new</TD></TR>
				<TR><TD PORT="packet_type_old_pos">1</TD><TD PORT="packet_type_old_size">4b</TD><TD>b4→PacketTags</TD><TD PORT="packet_type_old_type">packet_type_old</TD></TR>
				<TR><TD PORT="len_type_pos">1:4</TD><TD PORT="len_type_size">2b</TD><TD>b2</TD><TD PORT="len_type_type">len_type</TD></TR>
				<TR><TD PORT="body_pos">1:6</TD><TD PORT="body_size">...</TD><TD>switch (new_packet_format)</TD><TD PORT="body_type">body</TD></TR>
			</TABLE>>];
packet__seq_body_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
	<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
	<TR><TD>false</TD><TD PORT="case0">OldPacket</TD></TR>
</TABLE>>];
		}
		subgraph cluster__trust_signature {
			label="OpenpgpMessage::TrustSignature";
			graph[style=dotted];

			trust_signature__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="level_pos">0</TD><TD PORT="level_size">1</TD><TD>u1</TD><TD PORT="level_type">level</TD></TR>
				<TR><TD PORT="amount_pos">1</TD><TD PORT="amount_size">1</TD><TD>u1</TD><TD PORT="amount_type">amount</TD></TR>
			</TABLE>>];
		}
	}
	openpgp_message__seq:packets_type -> packet__seq [style=bold];
	secret_key_packet__seq:public_key_type -> public_key_packet__seq [style=bold];
	subpackets__seq:subpacketss_type -> subpacket__seq [style=bold];
	subpacket__seq:len_type -> len_subpacket__seq [style=bold];
	subpacket__seq:content_type -> subpacket__seq_content_switch [style=bold];
	subpacket__seq_content_switch:case0 -> exportable_certification__seq [style=bold];
	subpacket__seq_content_switch:case1 -> preferred_hash_algorithms__seq [style=bold];
	subpacket__seq_content_switch:case2 -> embedded_signature__seq [style=bold];
	subpacket__seq_content_switch:case3 -> trust_signature__seq [style=bold];
	subpacket__seq_content_switch:case4 -> reason_for_revocation__seq [style=bold];
	subpacket__seq_content_switch:case5 -> features__seq [style=bold];
	subpacket__seq_content_switch:case6 -> signature_expiration_time__seq [style=bold];
	subpacket__seq_content_switch:case7 -> preferred_compression_algorithms__seq [style=bold];
	subpacket__seq_content_switch:case8 -> revocable__seq [style=bold];
	subpacket__seq_content_switch:case9 -> regular_expression__seq [style=bold];
	subpacket__seq_content_switch:case10 -> notation_data__seq [style=bold];
	subpacket__seq_content_switch:case11 -> key_expiration_time__seq [style=bold];
	subpacket__seq_content_switch:case12 -> signature_creation_time__seq [style=bold];
	subpacket__seq_content_switch:case13 -> revocation_key__seq [style=bold];
	subpacket__seq_content_switch:case14 -> key_flags__seq [style=bold];
	subpacket__seq_content_switch:case15 -> issuer__seq [style=bold];
	subpacket__seq_content_switch:case16 -> signature_target__seq [style=bold];
	subpacket__seq_content_switch:case17 -> key_server_preferences__seq [style=bold];
	subpacket__seq_content_switch:case18 -> signers_user_id__seq [style=bold];
	subpacket__seq_content_switch:case19 -> policy_uri__seq [style=bold];
	subpacket__seq_content_switch:case20 -> preferred_key_server__seq [style=bold];
	subpacket__seq_content_switch:case21 -> primary_user_id__seq [style=bold];
	subpacket__seq:subpacket_type_type -> subpacket__seq:content_type [color="#404040"];
	old_packet__seq:len_type -> old_packet__seq_len_switch [style=bold];
	packet__seq:len_type_type -> old_packet__seq:len_type [color="#404040"];
	old_packet__seq:body_type -> old_packet__seq_body_switch [style=bold];
	old_packet__seq_body_switch:case0 -> public_key_packet__seq [style=bold];
	old_packet__seq_body_switch:case1 -> public_key_packet__seq [style=bold];
	old_packet__seq_body_switch:case2 -> user_id_packet__seq [style=bold];
	old_packet__seq_body_switch:case3 -> secret_key_packet__seq [style=bold];
	old_packet__seq_body_switch:case4 -> signature_packet__seq [style=bold];
	old_packet__seq_body_switch:case5 -> public_key_packet__seq [style=bold];
	packet__seq:packet_type_old_type -> old_packet__seq:body_type [color="#404040"];
	signature_packet__seq:len_hashed_subpacket_type -> signature_packet__seq:hashed_subpackets_size [color="#404040"];
	signature_packet__seq:hashed_subpackets_type -> subpackets__seq [style=bold];
	signature_packet__seq:len_unhashed_subpacket_type -> signature_packet__seq:unhashed_subpackets_size [color="#404040"];
	signature_packet__seq:unhashed_subpackets_type -> subpackets__seq [style=bold];
	embedded_signature__seq:signature_packet_type -> signature_packet__seq [style=bold];
	len_subpacket__seq:first_octet_type -> len_subpacket__inst__len [color="#404040"];
	len_subpacket__seq:first_octet_type -> len_subpacket__inst__len [color="#404040"];
	len_subpacket__seq:first_octet_type -> len_subpacket__inst__len [color="#404040"];
	len_subpacket__seq:first_octet_type -> len_subpacket__inst__len [color="#404040"];
	len_subpacket__seq:first_octet_type -> len_subpacket__inst__len [color="#404040"];
	len_subpacket__seq:second_octet_type -> len_subpacket__inst__len [color="#404040"];
	len_subpacket__seq:scalar_type -> len_subpacket__inst__len [color="#404040"];
	notation_data__seq:len_name_type -> notation_data__seq:name_size [color="#404040"];
	notation_data__seq:len_value_type -> notation_data__seq:value_size [color="#404040"];
	public_key_packet__seq:len_alg_type -> public_key_packet__seq:rsa_n_size [color="#404040"];
	packet__seq:body_type -> packet__seq_body_switch [style=bold];
	packet__seq_body_switch:case0 -> old_packet__seq [style=bold];
	packet__seq:new_packet_format_type -> packet__seq:body_type [color="#404040"];
}