Class: IOStreams::Pgp::Writer
- Defined in:
- lib/io_streams/pgp/writer.rb
Class Attribute Summary collapse
-
.audit_recipient ⇒ Object
Encrypt all pgp output files with this recipient for audit purposes.
-
.default_signer ⇒ Object
writeonly
Sign all encrypted files with this users key.
-
.default_signer_passphrase ⇒ Object
writeonly
Passphrase to use to open the private key when signing the file.
Attributes inherited from Writer
Class Method Summary collapse
-
.file(file_name, encrypt: true, recipient: nil, import_and_trust_key: nil, import_and_trust_level: 5, signer: default_signer, signer_passphrase: default_signer_passphrase, compress: :zip, compress_level: 6) ⇒ Object
Write to a PGP / GPG file, encrypting and/or signing the contents as it is written.
Methods inherited from Writer
Constructor Details
This class inherits a constructor from IOStreams::Writer
Class Attribute Details
.audit_recipient ⇒ Object
Encrypt all pgp output files with this recipient for audit purposes. Allows the generated pgp files to be decrypted with this email address. Useful for audit or problem resolution purposes.
18 19 20 |
# File 'lib/io_streams/pgp/writer.rb', line 18 def audit_recipient @audit_recipient end |
.default_signer=(value) ⇒ Object
Sign all encrypted files with this users key. Default: Do not sign encrypted files.
9 10 11 |
# File 'lib/io_streams/pgp/writer.rb', line 9 def default_signer=(value) @default_signer = value end |
.default_signer_passphrase=(value) ⇒ Object
Passphrase to use to open the private key when signing the file. Default: None.
13 14 15 |
# File 'lib/io_streams/pgp/writer.rb', line 13 def default_signer_passphrase=(value) @default_signer_passphrase = value end |
Class Method Details
.file(file_name, encrypt: true, recipient: nil, import_and_trust_key: nil, import_and_trust_level: 5, signer: default_signer, signer_passphrase: default_signer_passphrase, compress: :zip, compress_level: 6) ⇒ Object
Write to a PGP / GPG file, encrypting and/or signing the contents as it is written.
file_name: [String]
Name of file to write to.
encrypt: [true|false]
Whether to encrypt the file for the supplied recipient(s).
When set to false the file is signed but not encrypted, in which case a
:signer must be supplied and :recipient / :import_and_trust_key are ignored.
Default: true
recipient: [String|Array<String>]
One or more emails of users for which to encrypt the file.
Ignored when encrypt is false.
import_and_trust_key: [String|Array<String>]
One or more pgp keys to import and then use to encrypt the file.
Note: Ascii Keys can contain multiple keys, only the last one in the file is used.
import_and_trust_level: [Integer]
The owner-trust level to assign to keys supplied via :import_and_trust_key.
1 : Undefined (no opinion)
2 : Never (do not trust)
3 : Marginal
4 : Full
5 : Ultimate
Default: 5 : Ultimate
SECURITY WARNING:
Only import and trust keys received from a verified, trusted source.
The default trust level is `5` (Ultimate), which tells GPG to treat the imported key
as if it were one of your own keys. An ultimately trusted key is implicitly valid and
can in turn confer validity on other keys it has signed. Importing an attacker supplied
key at this level allows that attacker to impersonate other recipients.
When the key cannot be fully verified, supply a lower `import_and_trust_level`.
signer: [String]
Name of user with which to sign the encypted file.
Default: default_signer or do not sign.
signer_passphrase: [String]
Passphrase to use to open the private key when signing the file.
Default: default_signer_passphrase
compress: [:none|:zip|:zlib|:bzip2]
Note: Standard PGP only supports :zip.
:zlib is better than zip.
:bzip2 is best, but uses a lot of memory and is much slower.
Default: :zip
compress_level: [Integer]
Compression level
Default: 6
Note: There is intentionally no option here to disable MDC (Modification Detection Code) integrity protection on the files we produce. The reader exposes ‘ignore_mdc_error:` so we can consume legacy files that lack MDC (see Reader), but we never want to generate them: MDC is what protects the encrypted contents against tampering, and modern GnuPG mandates it for current ciphers anyway (`–disable-mdc` is a no-op unless an obsolete cipher is forced). Omitting MDC on output would only weaken files we create, with no upside for this library.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/io_streams/pgp/writer.rb', line 90 def self.file(file_name, encrypt: true, recipient: nil, import_and_trust_key: nil, import_and_trust_level: 5, signer: default_signer, signer_passphrase: default_signer_passphrase, compress: :zip, compress_level: 6) if encrypt raise(ArgumentError, "Requires either :recipient or :import_and_trust_key") unless recipient || import_and_trust_key elsif !signer raise(ArgumentError, "Requires a :signer when encrypt is false") end compress_level = 0 if compress == :none recipients = if encrypt collect_recipients(recipient, import_and_trust_key, import_and_trust_level) else [] end # Write to stdin, with the encrypted and/or signed contents being written to the file args = build_args( file_name: file_name, encrypt: encrypt, signer: signer, signer_passphrase: signer_passphrase, compress: compress, compress_level: compress_level, recipients: recipients ) command = IOStreams::Pgp.gpg_command(*args) # Do not log the command, it may contain the signer passphrase. action = encrypt ? "encrypt" : "sign" IOStreams.logger&.debug { "IOStreams::Pgp::Writer.open: #{action} -o #{file_name}" } result = nil Open3.popen2e(*command) do |stdin, out, waith_thr| begin stdin.binmode result = yield(stdin) stdin.close rescue Errno::EPIPE # Ignore broken pipe because gpg terminates early due to an error ::FileUtils.rm_f(file_name) raise(Pgp::Failure, "GPG Failed writing to encrypted file: #{file_name}: #{out.read.chomp}") end unless waith_thr.value.success? ::FileUtils.rm_f(file_name) raise(Pgp::Failure, "GPG Failed to create encrypted file: #{file_name}: #{out.read.chomp}") end end result end |