rnp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|