rnp 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +5 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.adoc +3 -182
  5. data/lib/rnp.rb +12 -3
  6. data/lib/rnp/error.rb +40 -0
  7. data/lib/rnp/ffi/librnp.rb +306 -0
  8. data/lib/rnp/input.rb +99 -0
  9. data/lib/rnp/key.rb +275 -0
  10. data/lib/rnp/misc.rb +71 -0
  11. data/lib/rnp/op/encrypt.rb +181 -0
  12. data/lib/rnp/op/sign.rb +139 -0
  13. data/lib/rnp/op/verify.rb +147 -0
  14. data/lib/rnp/output.rb +121 -0
  15. data/lib/rnp/rnp.rb +595 -0
  16. data/lib/rnp/utils.rb +44 -0
  17. data/lib/rnp/version.rb +8 -3
  18. metadata +124 -50
  19. data/.gitignore +0 -12
  20. data/.rspec +0 -2
  21. data/.travis.yml +0 -5
  22. data/CODE_OF_CONDUCT.md +0 -74
  23. data/Gemfile +0 -4
  24. data/Rakefile +0 -6
  25. data/Use_Cases.adoc +0 -119
  26. data/bin/console +0 -14
  27. data/bin/setup +0 -8
  28. data/example-usage.rb +0 -766
  29. data/examples/highlevel/decrypt_mem.rb +0 -44
  30. data/examples/highlevel/encrypt_mem.rb +0 -46
  31. data/examples/lowlevel/decrypt_file.rb +0 -76
  32. data/examples/lowlevel/decrypt_mem.rb +0 -80
  33. data/examples/lowlevel/encrypt_file.rb +0 -68
  34. data/examples/lowlevel/encrypt_mem.rb +0 -75
  35. data/examples/lowlevel/load_pubkey.rb +0 -118
  36. data/examples/lowlevel/print_keyring_file.rb +0 -68
  37. data/examples/lowlevel/print_keyring_mem.rb +0 -96
  38. data/examples/lowlevel/sign_file.rb +0 -104
  39. data/examples/lowlevel/sign_mem.rb +0 -96
  40. data/examples/lowlevel/verify_file.rb +0 -55
  41. data/examples/lowlevel/verify_mem.rb +0 -61
  42. data/lib/rnp/highlevel.rb +0 -5
  43. data/lib/rnp/highlevel/constants.rb +0 -96
  44. data/lib/rnp/highlevel/keyring.rb +0 -259
  45. data/lib/rnp/highlevel/publickey.rb +0 -150
  46. data/lib/rnp/highlevel/secretkey.rb +0 -318
  47. data/lib/rnp/highlevel/utils.rb +0 -119
  48. data/lib/rnp/lowlevel.rb +0 -6
  49. data/lib/rnp/lowlevel/constants.rb +0 -11
  50. data/lib/rnp/lowlevel/dynarray.rb +0 -129
  51. data/lib/rnp/lowlevel/enums.rb +0 -243
  52. data/lib/rnp/lowlevel/libc.rb +0 -28
  53. data/lib/rnp/lowlevel/libopenssl.rb +0 -15
  54. data/lib/rnp/lowlevel/librnp.rb +0 -213
  55. data/lib/rnp/lowlevel/structs.rb +0 -541
  56. data/lib/rnp/lowlevel/utils.rb +0 -25
  57. data/rnp.gemspec +0 -35
  58. data/rnp/lib/rnp.rb +0 -5
  59. data/rnp/spec/rnp_spec.rb +0 -11
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "rnp"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,766 +0,0 @@
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
-