rnp 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +26 -0
- data/README.adoc +208 -0
- data/Rakefile +6 -0
- data/Use_Cases.adoc +119 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example-usage.rb +766 -0
- data/examples/highlevel/decrypt_mem.rb +44 -0
- data/examples/highlevel/encrypt_mem.rb +46 -0
- data/examples/lowlevel/decrypt_file.rb +76 -0
- data/examples/lowlevel/decrypt_mem.rb +80 -0
- data/examples/lowlevel/encrypt_file.rb +68 -0
- data/examples/lowlevel/encrypt_mem.rb +75 -0
- data/examples/lowlevel/load_pubkey.rb +118 -0
- data/examples/lowlevel/print_keyring_file.rb +68 -0
- data/examples/lowlevel/print_keyring_mem.rb +96 -0
- data/examples/lowlevel/sign_file.rb +104 -0
- data/examples/lowlevel/sign_mem.rb +96 -0
- data/examples/lowlevel/verify_file.rb +55 -0
- data/examples/lowlevel/verify_mem.rb +61 -0
- data/lib/rnp/highlevel/constants.rb +96 -0
- data/lib/rnp/highlevel/keyring.rb +259 -0
- data/lib/rnp/highlevel/publickey.rb +150 -0
- data/lib/rnp/highlevel/secretkey.rb +318 -0
- data/lib/rnp/highlevel/utils.rb +119 -0
- data/lib/rnp/highlevel.rb +5 -0
- data/lib/rnp/lowlevel/constants.rb +11 -0
- data/lib/rnp/lowlevel/dynarray.rb +129 -0
- data/lib/rnp/lowlevel/enums.rb +243 -0
- data/lib/rnp/lowlevel/libc.rb +28 -0
- data/lib/rnp/lowlevel/libopenssl.rb +15 -0
- data/lib/rnp/lowlevel/librnp.rb +213 -0
- data/lib/rnp/lowlevel/structs.rb +541 -0
- data/lib/rnp/lowlevel/utils.rb +25 -0
- data/lib/rnp/lowlevel.rb +6 -0
- data/lib/rnp/version.rb +3 -0
- data/lib/rnp.rb +5 -0
- data/rnp/lib/rnp.rb +5 -0
- data/rnp/spec/rnp_spec.rb +11 -0
- data/rnp.gemspec +35 -0
- metadata +82 -9
data/example-usage.rb
ADDED
@@ -0,0 +1,766 @@
|
|
1
|
+
# Example usage of Rnp Ruby binding
|
2
|
+
|
3
|
+
module Rnp
|
4
|
+
|
5
|
+
# https://tools.ietf.org/html/rfc4880#section-4.1
|
6
|
+
# An OpenPGP message is constructed from a number of records that are
|
7
|
+
# traditionally called packets.
|
8
|
+
#
|
9
|
+
# https://tools.ietf.org/html/rfc4880#section-11
|
10
|
+
# OpenPGP packets are assembled into sequences in order to create
|
11
|
+
# messages and to transfer keys. Not all possible packet sequences are
|
12
|
+
# meaningful and correct.
|
13
|
+
class Message; end
|
14
|
+
|
15
|
+
# RFC 4880 11.1. Transferable Public Keys
|
16
|
+
# OpenPGP users may transfer public keys. The essential elements of a
|
17
|
+
# transferable public key are as follows:
|
18
|
+
# - One Public-Key packet
|
19
|
+
# - Zero or more revocation signatures
|
20
|
+
# - One or more User ID packets
|
21
|
+
# - After each User ID packet, zero or more Signature packets (certifications)
|
22
|
+
# - Zero or more User Attribute packets
|
23
|
+
# - After each User Attribute packet, zero or more Signature packets (certifications)
|
24
|
+
# - Zero or more Subkey packets
|
25
|
+
# - After each Subkey packet, one Signature packet, plus optionally a revocation
|
26
|
+
class PublicKeyMessage; end
|
27
|
+
# message.public_key_packet => PublicKeyPacketV(3 or 4)
|
28
|
+
# message.revocation_signatures => [] of Signatures
|
29
|
+
|
30
|
+
# RFC 4880 11.2. Transferable Secret Keys
|
31
|
+
# OpenPGP users may transfer secret keys. The format of a transferable
|
32
|
+
# secret key is the same as a transferable public key except that secret-key
|
33
|
+
# and secret-subkey packets are used instead of the public key and
|
34
|
+
# public-subkey packets. Implementations SHOULD include self- signatures on
|
35
|
+
# any user IDs and subkeys, as this allows for a complete public key to be
|
36
|
+
# automatically extracted from the transferable secret key. Implementations
|
37
|
+
# MAY choose to omit the self-signatures, especially if a transferable public
|
38
|
+
# key accompanies the transferable secret key.
|
39
|
+
class SecretKeyMessage; end
|
40
|
+
|
41
|
+
# RFC 4880 11.3. OpenPGP Messages
|
42
|
+
# An OpenPGP message is a packet or sequence of packets that corresponds to the
|
43
|
+
# following grammatical rules (comma represents sequential composition, and
|
44
|
+
# vertical bar separates alternatives):
|
45
|
+
#
|
46
|
+
# OpenPGP Message :- Encrypted Message | Signed Message | Compressed Message | Literal Message.
|
47
|
+
# Compressed Message :- Compressed Data Packet.
|
48
|
+
# Literal Message :- Literal Data Packet.
|
49
|
+
# ESK :- Public-Key Encrypted Session Key Packet | Symmetric-Key Encrypted Session Key Packet.
|
50
|
+
# ESK Sequence :- ESK | ESK Sequence, ESK.
|
51
|
+
# Encrypted Data :- Symmetrically Encrypted Data Packet | Symmetrically Encrypted Integrity Protected Data Packet
|
52
|
+
# Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data.
|
53
|
+
# One-Pass Signed Message :- One-Pass Signature Packet, OpenPGP Message, Corresponding Signature Packet.
|
54
|
+
# Signed Message :- Signature Packet, OpenPGP Message | One-Pass Signed Message.
|
55
|
+
class OpenPgpMessage < Message; end
|
56
|
+
|
57
|
+
# The user only needs to know about these
|
58
|
+
class LiteralMessage < OpenPgpMessage; end
|
59
|
+
class CompressedMessage < OpenPgpMessage; end
|
60
|
+
class EncryptedMessage < OpenPgpMessage; end
|
61
|
+
class SignedMessage < OpenPgpMessage; end
|
62
|
+
|
63
|
+
class OnePassSignedMessage < OpenPgpMessage; end
|
64
|
+
class EncryptedData; end
|
65
|
+
class EncryptedSessionKeySequence; end
|
66
|
+
class EncryptedSessionKey; end
|
67
|
+
|
68
|
+
# RFC 4880 11.4. Detached Signatures
|
69
|
+
# Some OpenPGP applications use so-called "detached signatures". For
|
70
|
+
# example, a program bundle may contain a file, and with it a second file
|
71
|
+
# that is a detached signature of the first file. These detached signatures
|
72
|
+
# are simply a Signature packet stored separately from the data for which
|
73
|
+
# they are a signature.
|
74
|
+
class Signature < Packet; end # a "Signature Packet"
|
75
|
+
|
76
|
+
# https://tools.ietf.org/html/rfc4880#section-4.1
|
77
|
+
# RFC 4880 Section 4-5
|
78
|
+
# A packet is a chunk of data that has a tag specifying its meaning. An
|
79
|
+
# OpenPGP message, keyring, certificate, and so forth consists of a number of
|
80
|
+
# packets. Some of those packets may contain other OpenPGP packets (for
|
81
|
+
# example, a compressed data packet, when uncompressed, contains OpenPGP
|
82
|
+
# packets).
|
83
|
+
class Packet; end
|
84
|
+
packet.type # RFC 4880 section 5
|
85
|
+
packet.version # version 3 or 4
|
86
|
+
packet.subpackets # sub-packets in Rnp::Packet format
|
87
|
+
packet.certify(key) # adds a certification signature after the packet
|
88
|
+
packet.parent # The parent packet if it is a subpacket
|
89
|
+
|
90
|
+
# 5.1. Public-Key Encrypted Session Key Packets (Tag 1)
|
91
|
+
class PublicKeyEncryptedSessionKeyPacket; end
|
92
|
+
# - A one-octet number giving the version number of the packet type. The
|
93
|
+
# currently defined value for packet version is 3.
|
94
|
+
packet.version # => 3 only
|
95
|
+
|
96
|
+
# - An eight-octet number that gives the Key ID of the public key to
|
97
|
+
# which the session key is encrypted. If the session key is
|
98
|
+
# encrypted to a subkey, then the Key ID of this subkey is used
|
99
|
+
# here instead of the Key ID of the primary key.
|
100
|
+
packet.public_key_id # => String Key ID
|
101
|
+
|
102
|
+
# - A one-octet number giving the public-key algorithm used.
|
103
|
+
packet.public_key_algorithm # => PublicKeyAlgorithm
|
104
|
+
|
105
|
+
# - A string of octets that is the encrypted session key. This string takes
|
106
|
+
# up the remainder of the packet, and its contents are dependent on the
|
107
|
+
# public-key algorithm used.
|
108
|
+
packet.encrypted_session_key # => String ciphertext
|
109
|
+
packet.decrypted_session_key # => String plaintext
|
110
|
+
|
111
|
+
# - Algorithm specific fields
|
112
|
+
# If RSA:
|
113
|
+
# - Multiprecision integer (MPI) of RSA encrypted value m**e mod n.
|
114
|
+
# { mpi: m**e mod n }
|
115
|
+
# If Elgamal:
|
116
|
+
# - MPI of Elgamal (Diffie-Hellman) value g**k mod p.
|
117
|
+
# - MPI of Elgamal (Diffie-Hellman) value m * y**k mod p.
|
118
|
+
# { first: g**k mod p, second: m* y**k mod p }
|
119
|
+
packet.algorithm_specific_fields
|
120
|
+
|
121
|
+
# 5.2. Signature Packet (Tag 2)
|
122
|
+
SignaturePacket = Signature # as defined above
|
123
|
+
# RFC 4880 5.2.2 (3 or 4)
|
124
|
+
signature.version
|
125
|
+
# RFC 4880 5.2.1 Signature Type
|
126
|
+
signature.type = [ # one of
|
127
|
+
SignatureType::GenericCertification,
|
128
|
+
SignatureType::PersonaCertification,
|
129
|
+
SignatureType::CasualCertification,
|
130
|
+
SignatureType::PositiveCertification,
|
131
|
+
SignatureType::SubkeyBinding,
|
132
|
+
SignatureType::PrimaryKeyBinding,
|
133
|
+
SignatureType::DirectKey,
|
134
|
+
SignatureType::KeyRevocation,
|
135
|
+
SignatureType::SubkeyRevocation,
|
136
|
+
SignatureType::CertificationRevocation,
|
137
|
+
SignatureType::Timestamp,
|
138
|
+
SignatureType::ThirdPartyConfirmation
|
139
|
+
]
|
140
|
+
signature.public_key_algorithm # PublicKeyAlgorithm
|
141
|
+
signature.hash_algorithm # HashAlgorithm
|
142
|
+
signature.to_s # ASCII armored signature
|
143
|
+
|
144
|
+
# SIGNATURE ATTRIBUTES (Subpackets of the Signature Packet)
|
145
|
+
# 5.2.3 Returns array of Subpackets
|
146
|
+
signature.hashed_subpackets
|
147
|
+
signature.unhashed_subpackets
|
148
|
+
# 5.2.3.4. Signature Creation Time
|
149
|
+
# DateTime
|
150
|
+
signature.creation_time
|
151
|
+
# 5.2.3.5. Issuer: The OpenPGP Key ID of the key issuing the signature.
|
152
|
+
signature.issuer
|
153
|
+
# 5.2.3.6. Key Expiration Time
|
154
|
+
# DateTime
|
155
|
+
signature.key_expiration_time
|
156
|
+
# 5.2.3.7. Preferred Symmetric Algorithms
|
157
|
+
# Ordered [] of preferred symmetric algorithms
|
158
|
+
signature.preferred_symmetric_algorithms
|
159
|
+
# 5.2.3.8. Preferred Hash Algorithms
|
160
|
+
# Ordered [] of preferred hash algorithms
|
161
|
+
signature.preferred_hash_algorithms
|
162
|
+
# 5.2.3.9. Preferred Compression Algorithms
|
163
|
+
# Ordered [] of preferred compression algorithms, :zip by default
|
164
|
+
signature.preferred_compression_algorithms
|
165
|
+
# 5.2.3.10. Signature Expiration Time
|
166
|
+
# DateTime
|
167
|
+
signature.signature_expiration_time
|
168
|
+
# 5.2.3.11. Exportable Certification
|
169
|
+
# Boolean
|
170
|
+
signature.exportable_certification
|
171
|
+
# 5.2.3.12. Revocable
|
172
|
+
# Boolean
|
173
|
+
signature.revocable
|
174
|
+
# 5.2.3.13. Trust Signature
|
175
|
+
# Integer 0-255
|
176
|
+
signature.trust_signature
|
177
|
+
# 5.2.3.14. Regular Expression
|
178
|
+
# RegExp
|
179
|
+
signature.regex
|
180
|
+
# 5.2.3.15. Revocation Key
|
181
|
+
signature.revocation_key # String of Key ID
|
182
|
+
signature.revocation_key_sensitive # Boolean
|
183
|
+
signature.revocation_key_algorithm # Key Algorithm
|
184
|
+
# 5.2.3.16. Notation Data
|
185
|
+
class NotationData; end
|
186
|
+
# Each NotationData has a :name (email address), :value (UTF8 string), a flag
|
187
|
+
# :human_readable
|
188
|
+
signature.notation_data.first.human_readable # Boolean, "human-readable"
|
189
|
+
# [] of NotationData, each is a { name (email) => value (UTF8 string) }
|
190
|
+
signature.notation_data
|
191
|
+
# 5.2.3.17. Key Server Preferences
|
192
|
+
signature.key_server_preferences_no_modify # Boolean
|
193
|
+
# 5.2.3.18. Preferred Key Server
|
194
|
+
signature.preferred_key_server # a URI String
|
195
|
+
# 5.2.3.19. Primary User ID
|
196
|
+
signature.primary_userid # Boolean
|
197
|
+
# 5.2.3.20. Policy URI
|
198
|
+
signature.policy_uri # a URI String
|
199
|
+
# 5.2.3.21. Key Flags
|
200
|
+
# The "split key" (0x10) and "group key" (0x80) flags are placed on a
|
201
|
+
# self-signature only; they are meaningless on a certification signature. They
|
202
|
+
# SHOULD be placed only on a direct-key signature (type 0x1F) or a subkey
|
203
|
+
# signature (type 0x18), one that refers to the key the flag applies to.
|
204
|
+
signature.key_flags # Can be combination of the following, :cert is always required.
|
205
|
+
[
|
206
|
+
:cert, # First octet 0x01, This key may be used to certify other keys.
|
207
|
+
:sign, # First octet 0x02, This key may be used to sign data.
|
208
|
+
:encrypt_comm, # First octet 0x04, This key may be used to encrypt communications.
|
209
|
+
:encrypt_data, # First octet 0x08, This key may be used to encrypt storage.
|
210
|
+
:auth, # First octet 0x20, This key may be used for authentication.
|
211
|
+
:split, # 0x10 - The private component of this key may have been split by a secret-sharing mechanism
|
212
|
+
:group, # 0x80 - The private component of this key may be in the possession of more than one person.
|
213
|
+
]
|
214
|
+
# 5.2.3.22. Signer's User ID
|
215
|
+
signature.userid # Userid object
|
216
|
+
# 5.2.3.23. Reason for Revocation
|
217
|
+
signature.revocation_code # one of :no_reason, :superseded, :compromised, :retired, :invalid
|
218
|
+
signature.revocation_reason # String
|
219
|
+
# 5.2.3.24. Features
|
220
|
+
signature.features # Not needed now
|
221
|
+
# 5.2.3.25. Signature Target
|
222
|
+
signature.target_public_key_algorithm # PublicKeyAlgorithm
|
223
|
+
signature.target_hash_algorithm # HashAlgorithm
|
224
|
+
signature.target_hash # String
|
225
|
+
# 5.2.3.26. Embedded Signature
|
226
|
+
signature.embedded_signature # => SignaturePacket
|
227
|
+
|
228
|
+
|
229
|
+
# 5.3. Symmetric-Key Encrypted Session Key Packets (Tag 3)
|
230
|
+
class SymmetricKeyEncryptedSessionKeyPacket; end
|
231
|
+
p.version # => 4
|
232
|
+
p.symmetric_algorithm # => SymmetricKeyAlgorithm
|
233
|
+
p.string_to_key # (S2K)
|
234
|
+
p.session_key
|
235
|
+
|
236
|
+
# 5.4. One-Pass Signature Packets (Tag 4)
|
237
|
+
class OnePassSignaturePacket; end
|
238
|
+
p.version # => 4
|
239
|
+
p.signature_type # => SignatureType
|
240
|
+
p.hash_algorithm # => HashAlgorithm
|
241
|
+
p.public_key_algorithm # => PublicKeyAlgorithm
|
242
|
+
p.key_id # => String
|
243
|
+
p.nested # => Boolean
|
244
|
+
|
245
|
+
# 5.5. Key Material Packet
|
246
|
+
# 5.5.1. Key Packet Variants
|
247
|
+
# 5.5.1.1. Public-Key Packet (Tag 6)
|
248
|
+
# 5.5.1.2. Public-Subkey Packet (Tag 14)
|
249
|
+
# 5.5.1.3. Secret-Key Packet (Tag 5)
|
250
|
+
# 5.5.1.4. Secret-Subkey Packet (Tag 7)
|
251
|
+
class KeyMaterialPacket; end
|
252
|
+
|
253
|
+
# 5.5.2. Public-Key Packet Formats
|
254
|
+
class PublicKeyPacketV3 < KeyMaterialPacket; end
|
255
|
+
class PublicSubkeyPacketV3 < PublicKeyPacketV3; end
|
256
|
+
# Methods
|
257
|
+
packet.version # => 3
|
258
|
+
packet.creation_time # => DateTime
|
259
|
+
packet.expiration_time # => Integer in days
|
260
|
+
packet.public_key_algorithm # => PublicKeyAlgorithm
|
261
|
+
packet.mpi # =>
|
262
|
+
# {
|
263
|
+
# n: "RSA MPI modulus n",
|
264
|
+
# e: "RSA MPI encryption exponent e"
|
265
|
+
# }
|
266
|
+
|
267
|
+
class PublicKeyPacketV4 < KeyMaterialPacket; end
|
268
|
+
class PublicSubkeyPacketV4 < PublicKeyPacketV4; end
|
269
|
+
# Methods
|
270
|
+
packet.version # => 4
|
271
|
+
packet.creation_time # => DateTime
|
272
|
+
packet.expiration_time # => Integer in days
|
273
|
+
packet.public_key_algorithm # => PublicKeyAlgorithm
|
274
|
+
# If RSA:
|
275
|
+
packet.mpi # => {
|
276
|
+
# n: RSA MPI modulus n
|
277
|
+
# e: RSA MPI encryption exponent e
|
278
|
+
# }
|
279
|
+
# If DSA:
|
280
|
+
packet.mpi # => {
|
281
|
+
# p: DSA prime p
|
282
|
+
# q: DSA group order q
|
283
|
+
# g: DSA group generator g
|
284
|
+
# y: DSA public key value y
|
285
|
+
# }
|
286
|
+
# If Elgamal:
|
287
|
+
packet.mpi # => {
|
288
|
+
# p: Elgamal prime p
|
289
|
+
# g: Elgamal group generator g
|
290
|
+
# y: Elgamal public key value y
|
291
|
+
# }
|
292
|
+
|
293
|
+
# 5.5.3. Secret-Key Packet Formats
|
294
|
+
class SecretKeyPacketV3 < PublicKeyPacketV3; end
|
295
|
+
class SecretSubkeyPacketV3 < SecretKeyPacketV3; end
|
296
|
+
class SecretKeyPacketV4 < PublicKeyPacketV4; end
|
297
|
+
class SecretSubkeyPacketV4 < SecretKeyPacketV4; end
|
298
|
+
# Methods (in addition to PublicKey methods above)
|
299
|
+
packet.public_key_packet # => PublicKeyPacketV3 || PublicSubkeyPacketV3
|
300
|
+
packet.string_to_key_usage # => 0-255
|
301
|
+
packet.symmetric_key_algorithm # (optional if usage is 255 or 254)
|
302
|
+
packet.string_to_key_specifier # (optional if usage is 255 or 254)
|
303
|
+
packet.iv # (optional, if secret key is encrypted)
|
304
|
+
packet.secret_key_data # => String
|
305
|
+
|
306
|
+
# If the string-to-key usage octet is zero or 255, then a two-octet checksum
|
307
|
+
# of the plaintext of the algorithm-specific portion (sum of all octets, mod
|
308
|
+
# 65536). If the string-to-key usage octet was 254, then a 20-octet SHA-1
|
309
|
+
# hash of the plaintext of the algorithm-specific portion. This checksum or
|
310
|
+
# hash is encrypted together with the algorithm-specific fields (if
|
311
|
+
# string-to-key usage octet is not zero). Note that for all other values, a
|
312
|
+
# two-octet checksum is required.
|
313
|
+
packet.checksum # => String
|
314
|
+
|
315
|
+
# If RSA secret key:
|
316
|
+
# {
|
317
|
+
# d: multiprecision integer (MPI) of RSA secret exponent d.
|
318
|
+
# p: MPI of RSA secret prime value p.
|
319
|
+
# q: MPI of RSA secret prime value q (p < q).
|
320
|
+
# u: MPI of u, the multiplicative inverse of p, mod q.
|
321
|
+
# }
|
322
|
+
# If DSA secret key:
|
323
|
+
# { x: MPI of DSA secret exponent x. }
|
324
|
+
# If Elgamal secret key:
|
325
|
+
# { x: MPI of Elgamal secret exponent x. }
|
326
|
+
packet.algorithm_specific_fields # => Hash
|
327
|
+
|
328
|
+
# 5.6. Compressed Data Packet (Tag 8)
|
329
|
+
class CompressedDataPacket; end
|
330
|
+
packet.algorithm # => CompressionAlgorithm
|
331
|
+
packet.data # => a valid decompressed Rnp::OpenPgpMessage
|
332
|
+
packet.to_s # => an armored compressed data packet
|
333
|
+
|
334
|
+
# 5.7. Symmetrically Encrypted Data Packet (Tag 9)
|
335
|
+
class SymmetricallyEncryptedDataPacket; end
|
336
|
+
packet.data # => [] of valid Rnp::Packet(s)
|
337
|
+
|
338
|
+
# 5.8. Marker Packet (Obsolete Literal Packet) (Tag 10)
|
339
|
+
class MarkerPacket; end
|
340
|
+
# The body of this packet consists of:
|
341
|
+
# - The three octets 0x50, 0x47, 0x50 (which spell "PGP" in UTF-8).
|
342
|
+
# Such a packet MUST be ignored when received.
|
343
|
+
packet.text # => "PGP"
|
344
|
+
|
345
|
+
# 5.9. Literal Data Packet (Tag 11)
|
346
|
+
class LiteralDataPacket; end
|
347
|
+
# A Literal Data packet contains the body of a message; data that is not to
|
348
|
+
# be further interpreted.
|
349
|
+
# - A one-octet field that describes how the data is formatted.
|
350
|
+
packet.format # => one of "b" (Binary), "t" (Text), "u" (UTF-8 text), "l" or
|
351
|
+
# "1" (Local) is deprecated.
|
352
|
+
packet.binary?
|
353
|
+
packet.text?
|
354
|
+
packet.utf8?
|
355
|
+
|
356
|
+
# - File name as a string (one-octet length, followed by a file name).
|
357
|
+
packet.filename # => String. Name of encrypted file or "_CONSOLE" (for your eyes only)
|
358
|
+
|
359
|
+
# - A four-octet number that indicates a date associated with the literal
|
360
|
+
# data.
|
361
|
+
packet.date # => DateTime, modification date of a file or the time packet was
|
362
|
+
# created, or 0 for no time
|
363
|
+
|
364
|
+
# - The remainder of the packet is literal data.
|
365
|
+
packet.data # => IO stream
|
366
|
+
packet.text # => If packet.text? then return text data with normalized <CR><LF> to local
|
367
|
+
|
368
|
+
# 5.10. Trust Packet (Tag 12)
|
369
|
+
class TrustPacket; end
|
370
|
+
# Only used in Keyrings
|
371
|
+
|
372
|
+
# 5.11. User ID Packet (Tag 13)
|
373
|
+
class UserIdPacket; end
|
374
|
+
# A RFC 2822 mail-addr.
|
375
|
+
# Same as class Rnp::Userid
|
376
|
+
|
377
|
+
# 5.12. User Attribute Packet (Tag 17)
|
378
|
+
class UserAttributePacket < UserIdPacket; end
|
379
|
+
packet.subpackets # => [] of Subpackets
|
380
|
+
|
381
|
+
class UserAttributeSubpacket; end
|
382
|
+
subpacket.type # => Only "1" is allowed as ImageAttributeSubpacket
|
383
|
+
subpacket.body # => Body of subpacket
|
384
|
+
|
385
|
+
# 5.12.1. The Image Attribute Subpacket
|
386
|
+
class ImageAttributeSubpacket < UserAttributeSubpacket; end
|
387
|
+
imagesubpacket.version # => 1 (only 1 allowed)
|
388
|
+
imagesubpacket.encoding # => 1 (only 1 allowed, means "JPEG")
|
389
|
+
imagesubpacket.body # => JPEG file IO
|
390
|
+
|
391
|
+
# 5.13. Sym. Encrypted Integrity Protected Data Packet (Tag 18) ..49
|
392
|
+
class SymmetricallyEncryptedIntegrityProtectedDataPacket < SymmetricallyEncryptedDataPacket; end
|
393
|
+
# - A one-octet version number. The only currently defined value is 1.
|
394
|
+
packet.version # => 1 (only 1 allowed)
|
395
|
+
|
396
|
+
# - Encrypted data, the output of the selected symmetric-key cipher operating
|
397
|
+
# in Cipher Feedback mode with shift amount equal to the block size of the
|
398
|
+
# cipher (CFB-n where n is the block size).
|
399
|
+
packet.data # => [decrypted Packet(s) (last one must be a ModificationDetectionCodePacket)]
|
400
|
+
packet.plaintext_data # => [decrypted Packet(s) without the last one (the ModificationDetectionCodePacket)]
|
401
|
+
|
402
|
+
# The symmetric cipher used MUST be specified in a Public-Key or
|
403
|
+
# Symmetric-Key Encrypted Session Key packet that precedes the Symmetrically
|
404
|
+
# Encrypted Data packet.
|
405
|
+
packet.cipher_packet # => a preceding PublicKeyEncryptedSessionKeyPacket or
|
406
|
+
# SymmetricKeyEncryptedSessionKeyPacket
|
407
|
+
|
408
|
+
# packet.mdc_packet => the ModificationDetectionCodePacket at the end of its packet.data
|
409
|
+
|
410
|
+
# 5.14. Modification Detection Code Packet (Tag 19)
|
411
|
+
class ModificationDetectionCodePacket; end
|
412
|
+
# - A 20-octet SHA-1 hash of the preceding plaintext data of the
|
413
|
+
# Symmetrically Encrypted Integrity Protected Data packet, including prefix
|
414
|
+
# data, the tag octet, and length octet of the Modification Detection Code
|
415
|
+
# packet.
|
416
|
+
#
|
417
|
+
packet.hash # => SHA1 hash
|
418
|
+
packet.hash_algorithm # => SHA1 allowed only
|
419
|
+
|
420
|
+
# These provide easier user access to the Packet(s)
|
421
|
+
Userid = UserIdPacket;
|
422
|
+
PublicKey = PublicKeyMessage
|
423
|
+
SecretKey = SecretKeyMessage
|
424
|
+
|
425
|
+
# These are the algorithms, for user read-only
|
426
|
+
class PublicKeyAlgorithm; end
|
427
|
+
class SymmetricKeyAlgorithm; end
|
428
|
+
class HashAlgorithm; end
|
429
|
+
class CompressionAlgorithm; end
|
430
|
+
# Not required yet
|
431
|
+
# class Keyring; end
|
432
|
+
end
|
433
|
+
|
434
|
+
# READING AN EXISTING SECRET KEY
|
435
|
+
key = Rnp::SecretKey.import(File.read("privatekey.key"))
|
436
|
+
key.passphrase = "xxx" # => non-interactive method of providing passphrase
|
437
|
+
key.to_s # => ASCII armored PGP secret key
|
438
|
+
key.public_key # => Rnp::PublicKey object
|
439
|
+
|
440
|
+
# GENERATING A NEW KEY
|
441
|
+
key = Rnp::SecretKey.new
|
442
|
+
key.generate(
|
443
|
+
key_length: Integer,
|
444
|
+
public_key_algorithm: PublicKeyAlgorithm::RSA,
|
445
|
+
algorithm_params: { e: Integer }, # content is public_key_algorithm specific
|
446
|
+
userid: String || Userid,
|
447
|
+
hash_algorithm: HashAlgorithm,
|
448
|
+
symmetric_key_algorithm: SymmetricKeyAlgorithm
|
449
|
+
)
|
450
|
+
# => calls Rnp's
|
451
|
+
# pgp_rsa_new_selfsign_key(
|
452
|
+
# const int numbits,
|
453
|
+
# const unsigned long e,
|
454
|
+
# uint8_t *userid,
|
455
|
+
# const char *hashalg,
|
456
|
+
# const char *cipher
|
457
|
+
# )
|
458
|
+
#
|
459
|
+
# Generates the following structure for the SecretKeyMessage:
|
460
|
+
# (Note: a User ID certification signature packet is called a self-signature in
|
461
|
+
# RFC 4880)
|
462
|
+
# [
|
463
|
+
# (a Secret-Key packet) SecretKeyPacketV4 (contains a PublicKeyPacketV4),
|
464
|
+
# (a User ID packet) UserIdPacket with primary_userid set to true,
|
465
|
+
# (a User ID certification signature) SignaturePacket(subpackets: [
|
466
|
+
# type = PositiveCertification
|
467
|
+
# primary_userid = true
|
468
|
+
# ])
|
469
|
+
# ]
|
470
|
+
#
|
471
|
+
# RFC 4880 5.5.2
|
472
|
+
# OpenPGP implementations MUST create keys with version 4 format. V3 keys are
|
473
|
+
# deprecated; an implementation MUST NOT generate a V3 key, but MAY accept it.
|
474
|
+
key.version # must be 4
|
475
|
+
key.secret_key_packet # => its Secret-Key packet
|
476
|
+
key.userids # => [] with its User ID packets
|
477
|
+
key.userid_signatures # => [] of Signature Packets of its User ID packets
|
478
|
+
key.passphrase # sets the passphrase if non-blank
|
479
|
+
key.key_id # => key id of key
|
480
|
+
key.fingerprint # => fingerprint of key
|
481
|
+
|
482
|
+
key.key_length # length of key
|
483
|
+
# :rsa
|
484
|
+
# https://tools.ietf.org/html/rfc4880#section-13.5
|
485
|
+
# An implementation SHOULD NOT implement RSA keys of size less than 1024 bits.
|
486
|
+
#
|
487
|
+
# :dsa
|
488
|
+
# https://tools.ietf.org/html/rfc4880#section-13.6
|
489
|
+
# An implementation SHOULD NOT implement DSA keys of size less than 1024 bits.
|
490
|
+
# It MUST NOT implement a DSA key with a q size of less than 160 bits. DSA
|
491
|
+
# keys MUST also be a multiple of 64 bits, and the q size MUST be a multiple of
|
492
|
+
# 8 bits. The Digital Signature Standard (DSS) [FIPS186] specifies that DSA be
|
493
|
+
# used in one of the following ways:
|
494
|
+
# * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash
|
495
|
+
# * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash
|
496
|
+
# * 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash
|
497
|
+
# * 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash
|
498
|
+
#
|
499
|
+
# :elgamal # Unsupported in Rnp
|
500
|
+
# https://tools.ietf.org/html/rfc4880#section-13.7
|
501
|
+
# An implementation SHOULD NOT implement Elgamal keys of size less than 1024
|
502
|
+
# bits.
|
503
|
+
|
504
|
+
# The "self-signatures": adding requrirements to the key
|
505
|
+
userid = key.userids.first
|
506
|
+
self_sig = key.userid_signature(userid) # retrieve SignaturePacket for a given Userid
|
507
|
+
self_sig.key_flags = [:sign, :cert] # adds to a self-signature packet
|
508
|
+
self_sig.preferred_symmetric_algorithms = [
|
509
|
+
SymmetricKeyAlgorithm::Aes256,
|
510
|
+
SymmetricKeyAlgorithm::Aes192,
|
511
|
+
SymmetricKeyAlgorithm::Aes,
|
512
|
+
SymmetricKeyAlgorithm::Cast5
|
513
|
+
]
|
514
|
+
self_sig.preferred_hash_algorithms = [
|
515
|
+
HashAlgorithm::Sha512,
|
516
|
+
HashAlgorithm::Sha384,
|
517
|
+
HashAlgorithm::Sha256,
|
518
|
+
HashAlgorithm::Sha224
|
519
|
+
]
|
520
|
+
self_sig.preferred_compression_algorithms = [
|
521
|
+
CompressionAlgorithm::Zlib,
|
522
|
+
CompressionAlgorithm::Bzip2,
|
523
|
+
CompressionAlgorithm::Zip,
|
524
|
+
CompressionAlgorithm::Uncompressed
|
525
|
+
]
|
526
|
+
|
527
|
+
|
528
|
+
# Adding a subkey
|
529
|
+
#
|
530
|
+
|
531
|
+
subkey = SecretSubkeyPacketV4.new
|
532
|
+
subkey.generate(
|
533
|
+
key_length: Integer,
|
534
|
+
public_key_algorithm: PublicKeyAlgorithm,
|
535
|
+
algorithm_params: { e: Integer }, # content is public_key_algorithm specific
|
536
|
+
userid: String || Userid,
|
537
|
+
hash_algorithm: HashAlgorithm,
|
538
|
+
symmetric_key_algorithm: SymmetricKeyAlgorithm
|
539
|
+
)
|
540
|
+
subkey_self_sig = Signature.new
|
541
|
+
subkey_self_sig.type = SignatureType::SubkeyBinding
|
542
|
+
subkey_self_sig.userid = userid
|
543
|
+
subkey_self_sig.key_flags = [:encrypt_data, :encrypt_comm, :cert]
|
544
|
+
subkey_self_sig.key_expiration_time = DateTime
|
545
|
+
subkey_self_sig.creation_time = DateTime
|
546
|
+
|
547
|
+
# Adds subkey to key
|
548
|
+
key.add_subkey(subkey)
|
549
|
+
|
550
|
+
key.subkeys # => [] of SecretSubkeyPacketV4
|
551
|
+
key.subkey_signature(subkey) # => SignaturePacket of subkey
|
552
|
+
|
553
|
+
# Delegate to self-signature
|
554
|
+
key.expiration_time # => time in seconds after key creation time
|
555
|
+
key.creation_time # => key generation date in DateTime of key
|
556
|
+
key.flags # => [] of key flags
|
557
|
+
|
558
|
+
# key is now:
|
559
|
+
# [
|
560
|
+
# (a Secret-Key packet) SecretKeyPacketV4 (contains a PublicKeyPacketV4),
|
561
|
+
# (a User ID packet) UserIdPacket with primary_userid set to true,
|
562
|
+
# (a User ID certification signature) SignaturePacket(subpackets: [
|
563
|
+
# type = PositiveCertification
|
564
|
+
# primary_userid = true
|
565
|
+
# key_flags = [:sign, :cert]
|
566
|
+
# preferred_symmetric_algorithms = [
|
567
|
+
# SymmetricKeyAlgorithm::Aes256,
|
568
|
+
# SymmetricKeyAlgorithm::Aes192,
|
569
|
+
# SymmetricKeyAlgorithm::Aes,
|
570
|
+
# SymmetricKeyAlgorithm::Cast5
|
571
|
+
# ]
|
572
|
+
# preferred_hash_algorithms = [
|
573
|
+
# HashAlgorithm::Sha512,
|
574
|
+
# HashAlgorithm::Sha384,
|
575
|
+
# HashAlgorithm::Sha256,
|
576
|
+
# HashAlgorithm::Sha224
|
577
|
+
# ]
|
578
|
+
# preferred_compression_algorithms = [
|
579
|
+
# CompressionAlgorithm::Zlib,
|
580
|
+
# CompressionAlgorithm::Bzip2,
|
581
|
+
# CompressionAlgorithm::Zip,
|
582
|
+
# CompressionAlgorithm::Uncompressed
|
583
|
+
# ]
|
584
|
+
# ])
|
585
|
+
# (a Subkey packet) SecretSubkeyPacketV4 (contains a PublicSubkeyPacketV4),
|
586
|
+
# (a subkey binding signature) SignaturePacket(subpackets: [
|
587
|
+
# type = SubkeyBindingSignature
|
588
|
+
# userid = userid
|
589
|
+
# key_flags = [:encrypt_data, :encrypt_comm, :cert]
|
590
|
+
# key_expiration_time = DateTime
|
591
|
+
# creation_time = DateTime
|
592
|
+
# ]),
|
593
|
+
# ]
|
594
|
+
|
595
|
+
# Public Key Algorithms
|
596
|
+
# https://tools.ietf.org/html/rfc4880#section-9.1
|
597
|
+
# https://tools.ietf.org/html/rfc6637#section-5
|
598
|
+
# NOTE: Rnp only supports generation of RSA keys (see rsa_generate_keypair()
|
599
|
+
# in openssl_crypto.c)
|
600
|
+
PublicKeyAlgorithms = [
|
601
|
+
PublicKeyAlgorithm::Rsa, # RFC4880, ID 1, RSA Encrypt or Sign [HAC]
|
602
|
+
PublicKeyAlgorithm::RsaEncryptOnly, # RFC4880, ID 2, RSA Encrypt-Only [HAC]
|
603
|
+
PublicKeyAlgorithm::RsaSignOnly, # RFC4880, ID 3, RSA Sign-Only [HAC]
|
604
|
+
PublicKeyAlgorithm::Elgamal, # RFC4880, ID 16, Elgamal (Encrypt-Only) [ELGAMAL] [HAC]
|
605
|
+
PublicKeyAlgorithm::Dsa, # RFC4880, ID 17, DSA (Digital Signature Algorithm) [FIPS186] [HAC]
|
606
|
+
PublicKeyAlgorithm::Ecdh, # RFC6637, ID 18, ECDH public key algorithm
|
607
|
+
PublicKeyAlgorithm::Ecdsa # RFC6637, ID 19, ECDSA public key algorithm
|
608
|
+
]
|
609
|
+
# https://tools.ietf.org/html/rfc4880#section-13.5
|
610
|
+
# There are algorithm types for RSA Sign-Only, and RSA Encrypt-Only keys.
|
611
|
+
# These types are deprecated. The "key flags" subpacket in a signature is a
|
612
|
+
# much better way to express the same idea, and generalizes it to all
|
613
|
+
# algorithms. An implementation SHOULD NOT create such a key, but MAY
|
614
|
+
# interpret it.
|
615
|
+
# => Do not allow generation of :rsa_e or :rsa_s keys
|
616
|
+
|
617
|
+
# Symmetric Key Algorithms
|
618
|
+
# https://tools.ietf.org/html/rfc4880#section-9.2
|
619
|
+
# https://tools.ietf.org/html/rfc5581#section-3
|
620
|
+
# NOTE: Rnp only supports:
|
621
|
+
# { "cast5", PGP_SA_CAST5 },
|
622
|
+
# { "idea", PGP_SA_IDEA },
|
623
|
+
# { "aes128", PGP_SA_AES_128 },
|
624
|
+
# { "aes256", PGP_SA_AES_256 },
|
625
|
+
# { "camellia128", PGP_SA_CAMELLIA_128 },
|
626
|
+
# { "camellia256", PGP_SA_CAMELLIA_256 },
|
627
|
+
# { "tripledes", PGP_SA_TRIPLEDES },
|
628
|
+
# { NULL, 0 }
|
629
|
+
SymmetricKeyAlgorithms = [
|
630
|
+
SymmetricKeyAlgorithm::None, #RFC4880, ID 0, Plaintext or unencrypted data
|
631
|
+
SymmetricKeyAlgorithm::Idea, #RFC4880, ID 1, IDEA [IDEA]
|
632
|
+
SymmetricKeyAlgorithm::Tripledes, #RFC4880, ID 2, TripleDES (DES-EDE, [SCHNEIER] [HAC], 168 bit key derived from 192)
|
633
|
+
SymmetricKeyAlgorithm::Cast5, #RFC4880, ID 3, CAST5 (128 bit key, as per [RFC2144])
|
634
|
+
SymmetricKeyAlgorithm::Blowfish, #RFC4880, ID 4, Blowfish (128 bit key, 16 rounds) [BLOWFISH]
|
635
|
+
SymmetricKeyAlgorithm::Aes128, #RFC4880, ID 7, AES with 128-bit key [AES]
|
636
|
+
SymmetricKeyAlgorithm::Aes192, #RFC4880, ID 8, AES with 192-bit key
|
637
|
+
SymmetricKeyAlgorithm::Aes256, #RFC4880, ID 9, AES with 256-bit key
|
638
|
+
SymmetricKeyAlgorithm::Blowfish256, #RFC4880, ID 10, Twofish with 256-bit key [TWOFISH]
|
639
|
+
SymmetricKeyAlgorithm::Camellia128, #RFC4880, ID 11, Camellia with 128-bit key
|
640
|
+
SymmetricKeyAlgorithm::Camellia192, #RFC4880, ID 12, Camellia with 192-bit key
|
641
|
+
SymmetricKeyAlgorithm::Camellia256 #RFC4880, ID 13, Camellia with 256-bit key
|
642
|
+
]
|
643
|
+
|
644
|
+
# Hash Algorithms
|
645
|
+
# https://tools.ietf.org/html/rfc4880#section-9
|
646
|
+
# NOTE: Rnp only supports
|
647
|
+
# case PGP_HASH_MD5:
|
648
|
+
# case PGP_HASH_SHA1:
|
649
|
+
# case PGP_HASH_SHA256:
|
650
|
+
# case PGP_HASH_SHA384:
|
651
|
+
# case PGP_HASH_SHA512:
|
652
|
+
# case PGP_HASH_SHA224:
|
653
|
+
HashAlgorithms = [
|
654
|
+
HashAlgorithms::Md5, # RFC4880, ID 1, MD5 [HAC] Text: "MD5",
|
655
|
+
HashAlgorithms::Sha1, # RFC4880, ID 2, SHA-1 [FIPS180] Text: "SHA1"
|
656
|
+
HashAlgorithms::Ripemd160, # RFC4880, ID 3, RIPE-MD/160 [HAC] Text: "RIPEMD160"
|
657
|
+
HashAlgorithms::Sha256, # RFC4880, ID 8, SHA256 [FIPS180] Text: "SHA256"
|
658
|
+
HashAlgorithms::Sha384, # RFC4880, ID 9, SHA384 [FIPS180] Text: "SHA384"
|
659
|
+
HashAlgorithms::Sha512, # RFC4880, ID 10, SHA512 [FIPS180] Text: "SHA512"
|
660
|
+
HashAlgorithms::Sha224 # RFC4880, ID 11, SHA224 [FIPS180] Text: "SHA224"
|
661
|
+
]
|
662
|
+
|
663
|
+
# Compression Algorithms
|
664
|
+
# https://tools.ietf.org/html/rfc4880#section-9.3
|
665
|
+
# NOTE: Rnp supports all three
|
666
|
+
# case PGP_C_ZIP:
|
667
|
+
# case PGP_C_ZLIB:
|
668
|
+
# case PGP_C_BZIP2:
|
669
|
+
CompressionAlgorithms = [
|
670
|
+
CompressionAlgorithm::Uncompressed || :nil, # RFC4880, ID 0, Uncompressed
|
671
|
+
CompressionAlgorithm::Zip, # RFC4880, ID 1, ZIP [RFC1951]
|
672
|
+
CompressionAlgorithm::Zlib, # RFC4880, ID 2, ZLIB [RFC1950]
|
673
|
+
CompressionAlgorithm::Bzip2 # RFC4880, ID 3, BZip2 [BZ2]
|
674
|
+
]
|
675
|
+
|
676
|
+
|
677
|
+
# Verifying a PGP message
|
678
|
+
public_key.verify(message.signature, message.content)
|
679
|
+
secret_key.verify(message.signature, message.content)
|
680
|
+
|
681
|
+
# USER ID methods
|
682
|
+
# A User ID is the 'name-addr' specified in RFC 2822 3.4
|
683
|
+
# https://tools.ietf.org/html/rfc2822#section-3.4
|
684
|
+
userid = key.userids.first
|
685
|
+
# Note: Rnp pgp_get_userid
|
686
|
+
userid = Rnp::Userid.new(address: "joshuac@mail.net", name: "Josiah Carberry")
|
687
|
+
userid.address # => address of user id
|
688
|
+
userid.name # => name of user id
|
689
|
+
userid.to_s # => "Josiah Carberry <joshuac@mail.net>"
|
690
|
+
userid.primary_userid # => RFC 4880 5.2.3.19 is this the Primary User ID of a key? Only when userid is associated with key.
|
691
|
+
|
692
|
+
key.userids << userid # adds Rnp::Userid packet to a Message
|
693
|
+
# Note: Rnp pgp_add_userid
|
694
|
+
|
695
|
+
# SIGNATURE METHODS
|
696
|
+
signature = Rnp::Signature.import("detached_ascii_pgp_signature")
|
697
|
+
signature.verify(key, data)
|
698
|
+
|
699
|
+
# MESSAGE METHODS
|
700
|
+
message = Rnp::OpenPgpMessage.new
|
701
|
+
# Importing from ASCII armored PGP message
|
702
|
+
message.import_ascii(File.read("ascii_armored_pgp_message.txt"))
|
703
|
+
# Importing unarmored content
|
704
|
+
message.import_raw(File.read("base64_portion_of_multipart_email.eml"))
|
705
|
+
message.packets # => [] of Rnp::Packet objects
|
706
|
+
message.signature # => signature of message in Rnp::Signature
|
707
|
+
message.signer_userid # => signer in Rnp::Userid
|
708
|
+
message.signed? # => is message signed?
|
709
|
+
message.encrypted? # => is message encrypted?
|
710
|
+
message.decrypt(key) # => decrypt content of message
|
711
|
+
message.content # => decrypted content of message
|
712
|
+
|
713
|
+
# Plaintext OpenPGP message
|
714
|
+
plaintext_data = File.read("plaintext.txt")
|
715
|
+
literal_message = LiteralMessage.new(plaintext_data) # automatically creates a LiteralDataPacket inside
|
716
|
+
|
717
|
+
# Signed OpenPGP message
|
718
|
+
message = SignedMessage.new(literal_message)
|
719
|
+
message.content = literal_message # alternative to above
|
720
|
+
message.key = SecretKey
|
721
|
+
message.sign # => SignedMessage [SignaturePacket, LiteralMessage]
|
722
|
+
|
723
|
+
# Or
|
724
|
+
message = OnePassSignedMessage.new(
|
725
|
+
signature_type: PositiveCertification,
|
726
|
+
hash_algorithm: HashAlgorithm,
|
727
|
+
public_key_algorithm: PublicKeyAlgorithm,
|
728
|
+
key: SecretKey || PublicKey,
|
729
|
+
content: literal_message
|
730
|
+
) # => OnePassSignedMessage is an OpenPgpMessage
|
731
|
+
message.to_s # ASCII armored message
|
732
|
+
|
733
|
+
# Or
|
734
|
+
message = SignedMessage.new
|
735
|
+
# Automatically creates a LiteralMessage, which contains a Literal Data Packet
|
736
|
+
message.content = plaintext_data
|
737
|
+
message.key = SecretKey
|
738
|
+
message.signature_type = PositiveCertification
|
739
|
+
message.hash_algorithm = HashAlgorithm
|
740
|
+
message.public_key_algorithm = PublicKeyAlgorithm
|
741
|
+
|
742
|
+
# Encrypted OpenPGP message
|
743
|
+
message = EncryptedMessage.new
|
744
|
+
message.key = YourPublicKey
|
745
|
+
message.public_key_algorithm = PublicKeyAlgorithm
|
746
|
+
# Automatically creates this:
|
747
|
+
# EncryptedMessage (
|
748
|
+
# EncryptedSessionKeySequence (
|
749
|
+
# EncryptedSessionKey (
|
750
|
+
# PublicKeyEncryptedSessionKeyPacket
|
751
|
+
# ),
|
752
|
+
# EncryptedData (
|
753
|
+
# SymmetricallyEncryptedIntegrityProtectedDataPacket (
|
754
|
+
# LiteralPacket(plaintext_data)
|
755
|
+
# )
|
756
|
+
# )
|
757
|
+
# )
|
758
|
+
# )
|
759
|
+
message.content = plaintext_data
|
760
|
+
|
761
|
+
|
762
|
+
# ALGORITHM METHODS
|
763
|
+
algo = message.public_key_algorithm # => public key algorithm in Rnp::PublicKeyAlgorithm format
|
764
|
+
algo.name # => name of algo, e.g., RSA
|
765
|
+
algo.parameters # => parameters of algo used, e.g., RSA parameters (RFC 4880 Algorithm Specific Fields)
|
766
|
+
|